JDBC
Java DataBase Connectivity 是一个独立于特定数据库的管理系统,通用的 SQL 数据库存取和操作的公共接口。
定义了一组标准,为访问不同数据库提供了统一的途径。
JDBC 体系结构
JDBC 接口包括两个层面:
- 面向应用的 API,共程序员调用
- 面向数据库的 API,共厂商开发数据库的驱动程序
JDBC API
提供者:Java 官方
内容:供开发者调用的接口
java.sql 和 javax.sql
DriverManager 类
Connection 接口
Statement 接口
ResultSet 接口
DriverManager
提供者:Java 官方
作用:管理不同的 JDBC 驱动
JDBC 驱动
提供者:数据库厂商
作用:负责连接不同的数据库
JDBC 的使用
1、加载数据库驱动,Java 程序和数据库之间的桥梁。
//第一种方式
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//第二种方式
Class.forName("com.mysql.jdbc.Driver");
第二种方式是怎么进行数据库驱动加载注册的?为什么我们常用第二种方式?
一、第二种方式是怎么加载驱动的?
我们可以在 com.mysql.jdbc.Driver 源代码中找到
static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); }
我们可以看到,静态代码块中存在第一种方式注册驱动
在反射的学习中我们知道,通过反射可以将类加载到内存中,而在类加载到内存中的时候会先执行静态代码块。所以第二种方式的本质,还是第一种方式去注册驱动。
二、我们为什么会常用第二种方式呢?
我们可以发现,第二种方式的参数是一个字符串,字符串我们可以写在 xxx.properties 等配置文件中。
2、获取 Connection,Java 程序于数据库的一次链接。
String url = "jdbc:mysql://localhost:3306/jdbcdatabase";
String user = "root";
String password = "root";
Connection connection = DriverManager.getConnection(url,user,password);
3、创建 Statement 对象,由Connection 产生,执行 SQL 语句。
String sql = "insert into student(id,name) values(1,'duznzifan')";
PreparedStatement ps = connection.prepareStatement(sql);
int result = ps.executeUpdate();
System.out.println(result);
4、如果需要接受返回值,创建 ResultSet 对象,保存 Statement 执行之后所查询到的结果。
String sql = "select * from student";
PreparedStatement ps = connection.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
//迭代遍历
while(rs.next()){
Integer id = rs.getInt(1);
String name = rs.getString(2);
System.out.println("id="+id+", name="+name);
}
PreparedStatement
Statement 的子类,提供了 SQL 占位符(?)的功能
使用 Statement 进行开发会存在下面的两个问题:
- 需要斌饭拼接 String 字符串来写 SQL 语句,出错率高。
- 存在 SQL 注入的风险。
将 JDBC 中的一些信息写入到配置文件中
Test.java
package cf.duanzifan; import java.sql.*; import java.util.ResourceBundle; public class Test { public static void main(String[] args) { //使用资源绑定器绑定属性配置文件 ResourceBundle bundle = ResourceBundle.getBundle("resource/jdbc"); String driver = bundle.getString("driver"); String url = bundle.getString("url"); String user = bundle.getString("user"); String password = bundle.getString("password"); try { //注册驱动 Class.forName(driver); //获取连接 Connection connection = DriverManager.getConnection(url,user,password); //获取preparedStatement String sql = "select * from student"; PreparedStatement ps = connection.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()){ Integer id = rs.getInt(1); String name = rs.getString(2); System.out.println("id="+id+", name="+name); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } } }
配置文件(jdbc.properties)
driver = com.mysql.jdbc.Driver url = jdbc:mysql://localhost:3306/jdbcdatabase user = root password = root
目录结构
怎么理解 Connection 和 Statement
每次连接数据库都要有一个 connection 对象,当得到一个 connection 对象时,我们可以进行多次对数据库的操作(SQL),statement 就时向数据库发送 SQL 的对象
也就是说:一个 connection 可以有多个 statement