JDBC:是一种执行sql语句的Java APL,可以为多种关系类型数据库提供统一访问,它由一组用Java语言编写的类和接口组成。有了JDBC,Java人员只需要编写一次程序就可以访问不同的数据库。
JDBC APL:供程序员调用的接口与类,集成在Java.sql包中
DriverManager类:管理不同的JDBC驱动
Connection接口:与特定数据库连接
Statement接口:执行sql
PreparedStatement接口:执行sql
初始化驱动程序,这人样就可以打开与数据库的通信信道
Class.forName("com.mysql.cj.jdbc.Driver");
或者
DriverManager.registerDriver(new Driver());
这需要使用DriverManager.getConnection()方法创造一个Connection对象,他代表一个物理连接的数据库
Connection connection=DriverManager.getConnection(url,user,password);
URL:
jdbc:mysql://ip(127.0.0.1):端口(3306)/数据库名?serverTimezone=Asia/Sanghai
USER:用户名(root)
PASSWORD:密码
Statement st =connection.createStatement();
Statement中的方法:
【int类型】 excuteUpdate(String sql) 用于执行ddl语句和dml(增删改)语句 返回操作的行数
用于执行ddl语句返回0
用于执行dml语句返回操作的行数
【ResultSet类型】 excuteQuery(String sql)用于执行查询语句返回一个ResuSet集合
在sql语句中参数位置使用占位符,使用setXX方法向sql中设置参数
PrepareStatement ps = connection.prepareStatement(sql);
PrepreStatement中的方法:
【int类型】 executeUPdate(): 用于执行ddl语句和dml(增删改)语句,返回操作的行数
用于执行ddl语句返回0
用于执行dml语句返回操作行数
【ResultSet类型】executeQuery():用于执行查询语句返回一个ResultSet集合
每次操作完成后关闭与数据库交互的通道
connection.close();
st.close();
ps.close();
接下来就写一个例子来作为JDBC搭建的总结:
public class day1 {
? ?public static void main(String[] args) throws ClassNotFoundException, SQLException {
? ? ? ?//2.驱动注册
? ? ? ?//方法一:都是为了创造一个对象
? ? ? ?//Class.forName("com.mysql.cj.jdbc.Driver");//放射方式加载驱动
? ? ? ?//方式二:
? ? ? ?DriverManager.registerDriver(new Driver());
?
? ? ? ?//3.建立与数据库的连接
? ? ? ?String url="jdbc:mysql://127.0.0.1:3306/schooldb?serverTimezone=Asia/Shanghai";
? ? ? ?String user="root";
? ? ? ?String password="root";//这是我的密码qwq
? ? ? ?Connection connection = DriverManager.getConnection(url,user,password);
? ? ? ?System.out.println(connection);
?
? ? ? ?//4.发送sql
? ? ? ?Statement statement= connection.createStatement();
? ? ? ?statement.executeUpdate("insert into major(name)value('数学')");
?
//或者利用PreparedStatement发送
/*
PreparedStatement preparedStatement = connection.prepareStatement("insert into major(name)value(?)");
preparedStatement.setObject(1, "数学");
preparedStatement.executeUpdate();
*/
? ? ? ?//5.关闭连接
? ? ? ?statement.close();
? ? ? ?connection.close();
? }
}
?
结果:
代码的可读性和可维护性
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次
安全性
防止外来代码sql注入。PreparedStatement的预占位符只能插入一个值,而会过滤其他语句;但是Statement可以插入其他语句比如or 1=1之类的和原数据库不符的条件。
举例方便直观感受:
Statement:
Statement statement= connection.createStatement();
? ? ? ?statement.executeUpdate("insert into major(name)value('数学')");
PrearedStatement:
PreparedStatement preparedStatement = connection.prepareStatement("insert into major(name)value(?)");
? ? ? ?preparedStatement.setObject(1, "数学");
? ? ? ?preparedStatement.executeUpdate();
PreparedStatement和Statement中的executeQuery()方法中会返回一个ResultSe对象,查询结果就封装在此对象中
可以使用ResultSet中的next()方法获得下一行数据
使用getXXX(String name)方法获得值
举例:
有如下表:
有如下类保存学生数据:
public class Student {
? ?int number;
? ?String name;
? ?String gender;
? ?float height;
? ?Date regTime;
?
? ?public void setNumber(int number) {
? ? ? ?this.number = number;
? }
?
? ?public void setName(String name) {
? ? ? ?this.name = name;
? }
?
? ?public void setGender(String gender) {
? ? ? ?this.gender = gender;
? }
?
? ?public void setHeight(float height) {
? ? ? ?this.height = height;
? }
?
? ?public void setRegTime(Date regTime) {
? ? ? ?this.regTime = regTime;
? }
?
}
查询一个学生:
public class day2demo2 {
? ?public static void main(String[] args) throws SQLException {
? ? ? ?//查询学号为1的学生
? ? ? ?Student student=findStudentByNumber(1);
? ? ? ?System.out.println(student);
? }
?
? ?public static Student findStudentByNumber (int number) throws SQLException {
? ? ? ?DriverManager.registerDriver(new Driver());
? ? ? ?String url="jdbc:mysql://127.0.0.1:3306/schooldb?serverTimezone=Asia/Shanghai";
? ? ? ?String user="root";
? ? ? ?String password="root";
? ? ? ?//建立钰数据库的连接
? ? ? ?Connection connection= DriverManager.getConnection(url, user, password);
? ? ? ?//执行查询
? ? ? ?PreparedStatement ps = connection.prepareStatement("select number,name,gender,height,reg_time from student where number=?");
? ? ? ?ps.setObject(1, number);
? ? ? ?//执行查询后,mysql将数据分装到一个ResultSet中
? ? ? ?ResultSet re=ps.executeQuery();
? ? ? ?//将result中的数据重新包装到自己的对象中,使用起来更加方便
? ? ? ?Student student =new Student();
? ? ? ?while(re.next())
? ? ? {
? ? ? ? ? ?student.setNumber(re.getInt("number"));
? ? ? ? ? ?student.setGender(re.getNString("gender"));
? ? ? ? ? ?student.setName(re.getString("name"));
? ? ? ? ? ?student.setHeight(re.getFloat("height"));
? ? ? ? ? ?student.setRegTime(re.getTimestamp("reg_time"));
? ? ? }
? ? ? ?return student;
? }
}
?
结果:(显示地址)想要显示数据还要重写toString方法
查询全部学生:用Student类型的集合包装每个学生
public class day2demo {
?
/*
? ?获取数据库中的信息
*/
? ?public static void main(String[] args) throws SQLException {
? ? ? ?ArrayList<Student> students= ?findStudentByNumber();
? ? ? ?System.out.println(students);
? }
?
? ?public static ArrayList<Student> findStudentByNumber () throws SQLException {
? ? ? ?DriverManager.registerDriver(new Driver());
? ? ? ?String url="jdbc:mysql://127.0.0.1:3306/schooldb?serverTimezone=Asia/Shanghai";
? ? ? ?String user="root";
? ? ? ?String password="root";
? ? ? ?//建立钰数据库的连接
? ? ? ?Connection connection= DriverManager.getConnection(url, user, password);
? ? ? ?//执行查询
? ? ? ?PreparedStatement ps = connection.prepareStatement("select number,name,gender,height,reg_time from student");
? ? ? ?//执行查询后,mysql将数据分装到一个resultset中
? ? ? ?ResultSet re=ps.executeQuery();
? ? ? ?//用arraylist保存student数据
? ? ? ?ArrayList<Student> students = new ArrayList<>();
? ? ? ?while(re.next())
? ? ? {
? ? ? ? ? ?Student student =new Student();
? ? ? ? ? ?student.setNumber(re.getInt("number"));
? ? ? ? ? ?student.setGender(re.getNString("gender"));
? ? ? ? ? ?student.setName(re.getString("name"));
? ? ? ? ? ?student.setHeight(re.getFloat("height"));
? ? ? ? ? ?student.setRegTime(re.getTimestamp("reg_time"));
? ? ? ? ? ?students.add(student);
? ? ? }
? ? ? ?return students;
? }
}
结果: