JDBC
「英文时间」:JDBC Java Database Connectivity n. Java 数据库连接
关于数据库的重要性什么都不说了,如果 Java 语言连数据库都不支持,恐怕没有人会用它了。JDBC 是 Java 提供的一套关于数据库操作的接口规范,并没有提供具体的实现类,具体的实现类库是由各个数据库软件厂商提供的。所以 Java 程序员通过 JDBC 这套 API 就可以直接写出跨平台和跨数据库的应用程序,给人感觉很舒服,JDBC 的设计可以说是典型的面向接口编程的案例。

JDBC 常用接口和类
JDBC 中常用的就是这几个接口和类,下面分别介绍:
- 每一个数据库厂商提供的驱动必须实现
java.sql.Driver
接口,实现这个接口的类就作为驱动程序的入口。比如 Mysql 中就使用了com.mysql.jdbc.Driver
类实现了该接口,所以 JDBC 编程的第一步,就是使用反射技术将此类的字节码文件加载到内存中去,实现方式如下:Class.forName("com.mysql.jdbc.Driver")
。此类的内部有一个静态代码块,功能是将此类的对象放到java.sql.DriverManager
类中去,如下所示:
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
看到这里就明白了,JDBC 编程第一步为什么要先加载这个类的字节码文件到内存中去了,因为要执行它的静态代码块的内容,以将此 Driver 类添加到 DriverManager 类中进行管理啊。
-
java.sql.DriverManager
类是专门设计来进行管理驱动的,一般都是用它的getConnection(String url,String user,String pass)
方法来得到和数据库的 Connection 对象。 -
java.sql.Connection
接口代表 Java 程序和数据库的一个连接对象,它有三个方法得到代表 SQL 语句的声明对象。
- 通过
createStatement()
方法得到 Statement 声明对象 - 通过
prepareStatement(String sql)
方法得到 PreparedStatement 声明对象 - 通过它的
prepareCall(String sql)
方法得到 CallableStatement 声明对象,通过此对象来调用数据库中的存储过程。以前学习 Oracle 的时候,还不理解存储过程是怎么被程序使用的,原来这么简单。
-
java.sql.Statement
接口代表一个 SQL 语句,为什么用起名字叫做 Statement 呢?SQL 是一种声明式的编程语言,而 Statement 英文含义就是名词,声明的意思,可见它命名的用意。通常使用如下两种方式来实现执行 SQL 语句的功能:
- 使用
excuteUpdate(String sql)
方法执行增加、删除和修改操作 - 使用
excuteQuery(String sql)
方法执行查询操作,返回值为 ResultSet 集合。
-
java.sql.PreparedStatement
接口,也是代表一个 SQL 语句,和 Statement 的不同点是,它会对 SQL 语句进行预编译,所以它更加高效而且能够阻止 SQL 注入的风险,预编译的 SQL 语句可以使用占位符?
提前进行站位,然后 PreparedStatement 对象通过setXXX(int i,String s)
方法进行赋值。通常使用如下两种方式来实现执行 SQL 语句的功能:
- 使用
excuteUpdate()
方法执行增加、删除和修改操作 - 使用
excuteQuery()
方法执行查询操作,返回值为 ResultSet 集合。
-
java.sql.ResultSet
接口作为查询结果的集合,可以直接把它的数据结构想象成是和数据库中表结构一样的就可以了,它的第一个游标指向
所以,有没有发现上面讲到除了 DriverManager 是类,其他都是接口,所以完全可以在它的基础上进行封装,提供自己的一套实现类库,这在自己动手实现数据库连接池和自定义 DBUtils 类的过程中可以得到完整体现。
JDBC 编程简单示例
要实现 JDBC 编程首先需要将对应的数据库驱动 jar 包放到项目的 lib 目录下,然后开启数据库服务,等待 Java 程序去连接它。
/*通过之前的源码分析,可知此行代码将 Driver 类字节码文件添加到了内存中,并执行了它内部的静态代码块,以此将 Driver 驱动对象添加到了 DriverManager 类中去*/
Class.forName("com.mysql.jdbc.Driver");
//获得代表SQL语句的声明对象
Statement stmt = DriverManager.createStatement();
//ResultSet rs = stmt.excuteQuery("select * from student");
//遍历集合
while(rs.next()){
//输出...
}
对于 JDBC 编程其实就这么简单,理解上面的几个类和接口,实际编程中查查 API ,就不存在什么问题了。
进一步理解数据库连接 Connection
Java 程序中和 DBMS 建立 Connection 连接的过程,本质上就是在和 DBMS 建立网络连接,Java 程序将 SQL 语句发送给 DBMS 进行处理后,DBMS 再返回结果通过网络发送到 Java 程序进行接收。只是为了简化这个过程,就构建出了一个数据库连接的概念,来抽象代表这个繁琐的网络通信细节。抽象有时候是好事,变得更简单,却也阻挡了实际细节,有时候让人摸不着头脑。
它底层就是采用 Java 的 Socket 网络编程技术实现的,也就是 TCP 网络连接三次握手。由于 JDBC 定义的是接口规范,不提供具体的实现,也就是说底层复杂的网络通信和 IO 操作都是交由对应的数据库驱动去实现的,这就是为什么一定需要导入对应 DBMS 的驱动 jar 包的原因。JDBC 接口和驱动程序建立关联就是靠的那个实现了 java.sql.Driver 接口的类,也就是必须利用反射计数主动将其加载到内存中的那个类,依靠它才把底层驱动程序和 JDBC 接口建立起了关联。
所以说这个过程很消耗资源,如果用一次就关闭,再用就再去建立连接,那真的不仅消耗资源还浪费时间。正确的做法应该是建立一个连接池,实现数据库连接的复用。点此查看数据库连接池笔记