JDBC(Java DataBase Connectivity)java数据库连接。作用就是与数据库进行连接。
不同的数据库实现方式不同,java程序想要链接不同的数据库就需要实现不同的细节,会增加java程序员的工作量。为了解决这一问题java提供了JDBC。
是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它由一组Java语言编写的类和接口组成。
有了JDBC,java程序员只用编写一次程序,就可以调用不同的数据库。
三方关系:
java定义者制定了JDBC规范——>数据库开发商实现接口——>程序员学习使用标准规范。
如链接mysql数据库:
java中提供一个Connection接口mysql中有一个实现类ConnectionImplement(implements)实现,mysql开发商将链接mysql具体的实现功能封装到mysql-connector-java-版本 .jar文件中我们连接mysql时,只需要导入此包即可.
JDBC API:供程序员调用的接口与类,集成在java.sql包中
DriverManager类作用:管理各种不同的JDBC驱动;
Connection接口:与特定数据库的连接;
Statement接口:执行sql;
PreparedStatement:执行sql;
ResultSet接口:接收查询结果;
导入mysql的jar包
注册JDBC驱动程序
需要初始化驱动程序,这样就可以打开与数据库的通信信道。
Class.forName("com.mysql.cj.jdbc.Driver");//利用反射机制
//和
DriverManager.registerDriver(new Driver());
建立与数据库连接:
//这里需要使用DriverManager.getConnection()方法来创建一个connection对象,他代表一个物理连接的数据库
Connection connection = DriverMan ager.getConnection("jdbc:mysql://127.0.0.1:3306/schooldb?character Encoding=utf8&serverTimezone=Asia/Shanghai","root","1222");
/*
其中的
URL:jdbc:mysql://127.0.0.1:3306/schooldb?serverTimezone=Asia/Shanghai 127.0.0.1:3306——>ip+端口,schooldb——>数据库
“root”表示用户名 ,“1222”数据库密码。
连接MySQL8时必须设置时区serverTimezone=Asia/Shanghai
*/
Statement st = connection.createStatement();
Satement中的方法:
int executeUpdate(String sql)用于执行ddl语句和dml(增删改)语句。
用于执行ddl语句返回0,用于执行dml语句返回操作的行数。
ResultSet executeQuery(String sql);用于执行查询语句,返回一个ResultSet集合。
在sql语句中参数位置使用占位符,使用setXXX方法向sql中设置参数
PreparedStatement ps = connection.prepareStatement(sql);
PreparedStatement中的方法:
int executeUpdate()用于执行ddl语句和dml(增删改)语句。
用于执行ddl语句返回0,用于执行dml语句返回操作的行数。
ResultSet executeQuery();用于执行查询语句,返回一个ResultSet集合。
关闭与数据库的链接通道
每次操作完成后关闭所有与数据库交互的通道
st.close();
connection.close();
ps.close();
总体代码如下:
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//初始化驱动程序
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/schooldb?serverTimezone=Asia/Shanghai","root","1222");
String name = "小天";
String num ="1478965230";
float h = 1.69f;
String a = "汉中";
//使用Statement
Statement st = connection.createStatement();
//执行sql语句
st.executeUpdate("INSERT INTO students(num,sname,height,addres)"+"VALUES ('"+num+"','"+name+"','"+h+"','"+a+"')");
//使用PreparedStatement
PreparedStatement ps = connection.prepareStatement("insert into students(num,sname,height,addres) values (?,?,?,?)");
ps.setObject(1,num);
ps.setObject(2,name);
ps.setObject(3,h);
ps.setObject(4,a);
ps.executeUpdate();//执行sql
//关闭链接
st.close();
ps.close();
connection.close();
}
代码的可读性和维护性
虽然PreparedStatement 来代替Statement会多几行代码,但是这样的代码无论从可读性还是可维护性上来说,都比直接用Statement要好很多。
//使用Statement
Statement st = connection.createStatement();
//执行sql语句
st.executeUpdate("INSERT INTO students(num,sname,height,addres)"+"VALUES ('"+num+"','"+name+"','"+h+"','"+a+"')");
//使用PreparedStatement
PreparedStatement ps = connection.prepareStatement("insert into students(num,sname,height,addres) values (?,?,?,?)");
ps.setObject(1,num);
ps.setObject(2,name);
ps.setObject(3,h);
ps.setObject(4,a);
ps.executeUpdate();//执行sql
最重要的是极大地提高安全性
防止sql注入
如果sql语句是:“delete from where num = ”+num;
此时如果我们把[or 1=1]传进去,因为1=1恒成立所以当使用Statement时会造成数据操作失误,因为使用PreparedStatement时会预编译,在预编译模式中每个占位符处,只能插入一个值,而且会过滤其他语句。
PreparedStatement和Statement中的executeQuery()方法中会返回一个ResultSet对象,查询结果就封装在此对象中。
使用ResultSet中的next()方法获得下一行数据
使用getXXX(String name)方法获得值
如下一个相对比较正规的例子:
public Students findStudentById(String id) throws SQLException, ClassNotFoundException {
Students student = new Students();
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/schooldb?serverTimezone=Asia/Shanghai";
Connection connection = DriverManager.getConnection(url, "root", "1222");
String sql = "SELECT id , num , sname , gender , birthday , phone FROM students WHERE id = ?" ;
PreparedStatement ps = connection.prepareStatement(sql);
ps.setObject(1,id);
ResultSet resultSet = ps.executeQuery();//将结果封装在ResultSet集合中
/*
//next()方法获得下一行数据
起始的时候使用next()方法是获得第一行数据,集合中当所有的数据遍历完后跳出循环
*/
while (resultSet.next()) {
student.setId(resultSet.getInt("id"));
student.setNum(resultSet.getString("num"));
student.setName(resultSet.getString("sname"));
student.setGender(resultSet.getString("gender"));
student.setBirthday(resultSet.getTimestamp("birthday"));
student.setPhone(resultSet.getString("phone"));
}
} finally {
connection.close();
ps.close();
resultSet.close();
return student;
}
}