通过使用JDBC,Java程序可以轻松地操作各种主流数据库,例如,Oracle、MS SQL Server、MySQL等。由于Java语言本身的跨平台性,所以使用JDBC编写的程序不仅可以实现跨数据库,还具有跨平台性和可移植性。使用JDBC访问数据库具有操作简单、获取方便且安全可靠等优势。
JDBC简介
JDBC(Java Database Connectivity,Java数据库连接)是一种执行SQL语句的Java API。程序可以通过JDBC API连接到关系数据库,并使用SQL结构化语言来完成对数据库的增、删、改、查等操作。与其他数据库编程语言相比,JDBC为数据开发者提供了标准的API,使用JDBC开发的数据库应用程序可以访问不同的数据库,并在不同平台上运行,既可以在Windows平台上运行,也可以在UNIX平台上运行。
JDBC程序访问不同的数据库时,需要数据库厂商提供相应的驱动程序。通过JDBC驱动程序的转换,使得相同的代码在访问不同的数据库时运行良好。JDBC驱动示意图如图14.1所示。
JDBC应用程序可以对数据库进行访问和操作,JDBC访问数据库时主要完成以下工作:
● 建立与数据库的连接;
● 执行SQL语句;
● 获取执行结果。
JDBC驱动
数据库驱动程序是JDBC程序和数据库之间的转换层,数据库驱动程序负责将JDBC调用映射成特定的数据库调用,JDBC访问示意图如图14.2所示。
JDBC驱动
当今市场上主流数据库都提供了JDBC驱动程序,甚至一些流行的数据库还提供了多种不同版本的JDBC驱动程序。
JDBC驱动程序有以下4种类型:
● JDBC-ODBC桥:是最早实现的JDBC驱动程序,主要目的是快速推广JDBC。ODBC(Open Database Connectivity,开放数据库连接)是通过一组通用的API访问不同的数据库管理系统,也需要各数据库厂商提供相应的驱动程序,而ODBC则对这些驱动程序进行管理。JDBC-ODBC桥驱动是将JDBC API映射到ODBC API,驱动速度很慢,只适用于访问没有其他JDBC驱动的数据库。由于Java语言的广泛应用,所有数据库厂商都提供了JDBC驱动,因此在Java 8中不再支持JDBC-ODBC数据访问方式。
● 本地API驱动:直接将JDBC API映射成数据库特定的客户端API,包含特定的数据库本地代码,用于访问特定数据库的客户端。本地API驱动比起JDBC-ODBC桥执行效率要高,但是仍然需要在客户端加载数据库厂商提供的代码库,不适合基于网络的应用。本地API驱动虽然速度有所提升,但相对后面两种JDBC驱动还是不够高。
● 网络协议驱动:将JDBC调用翻译成中间件供应商的协议,然后再由中间件服务器翻译成数据库访问协议。网络协议驱动是基于服务器的,不需要在客户端加载数据库厂商提供的代码库,且执行效率比较好,便于维护和升级。
● 本地协议驱动:是纯Java编写的,可以直接连接到数据库。本地协议驱动不需要将JDBC的调用传给ODBC,或本地数据库接口,或中间层服务器,因此执行效率非常高;而且根本不需要在客户端或服务器装载任何软件或驱动。本地协议驱动是智能的,能够知道数据库使用的底层协议,是目前最流行的JDBC驱动。
通常JDBC访问数据库时建议使用第4种本地协议驱动,该驱动使用纯Java编写,且避开了本地代码,减少了应用开发的复杂性,降低了产生冲突和出错的可能。
JDBC API
JDBC API提供了一组用于与数据库进行通信的接口和类,这些接口和类都定义在java.sql包中,常用的接口和类如表14-1所示。
需要注意的是:使用JDBC API中的类或接口访问数据库时,容易引发SQLException异常,SQLException异常类是检查型异常,需要放在try…catch语句中进行异常处理,SQLException是JDBC中其他异常类型的基础。
1. DriverManager类
DriverManager是数据库驱动管理类,用于管理一组JDBC驱动程序的基本服务。应用程序和数据库之间可以通过DriverManager建立连接,其常用的静态方法如表14-2所示。
2. Connection接口
Connection接口用于连接数据库,每个Connection对象代表一个数据库连接会话,要想访问数据库,必须先获得数据库连接。一个应用程序可与单个数据库建立一个或多个连接,也可以与多个数据库建立连接。通过DriverManager类的getConnection()方法可以返回一个Connection对象,该对象中提供了创建SQL语句的方法,以完成基本的SQL操作,同时为数据库事务提供了提交和回滚的方法。Connection接口中常用的方法如表14-3所示。
3. Statement接口
Statement接口一般用于执行SQL语句。在JDBC中要执行SQL查询语句的方式有一般查询(Statement)、参数查询(PreparedStatement)和存储过程(CallableStatement)三种方式。Connection接口中提供的createStatement()、prepareStatement()和prepareCall()方法分别返回一个Statement对象,PreparedStatement对象和CallableStatement对象。
Statement、PreparedStatement和CallableStatement三个接口具有继承关系,其中PreparedStatement是Statement的子接口,而CallableStatement又是PreparedStatement的子接口。Statement接口的主要功能是将SQL语句传送给数据库,并返回SQL语句的执行结果。Statement提交的SQL语句是静态的,不需要接收任何参数,SQL语句可以包含以下三种类型的语句:
● SELECT查询语句;
● DML语句,如INSERT、UPDATE或DELETE;
● DDL语句,如CREATE TABLE和DROP TABLE。
Statement接口中常用的方法及功能如表14-4所示。
需要注意的是:closeOnCompletion()和isCloseOnCompletion()方法是从Java 7开始新增的方法,executeLargeUpdate()方法是从Java 8开始新增的方法,在开发过程中使用这几个方法时需要注意JDK的版本。考虑到目前应用程序所处理的数据量越来越大,使用executeLargeUpdate()方法具有更好的适应性,但目前有的数据库驱动暂不支持该方法,例如MySQL驱动。
4. ResultSet接口
ResultSet接口用于封装结果集对象,该对象包含访问查询结果的方法。使用Statement中的executeQuery()方法可以返回一个ResultSet结果集的对象,该对象封装了所有符合查询条件的记录。
ResultSet具有指向当前数据行的游标,并提供了许多方法来操作结果集中的游标,同时还提供了一套getXXX()方法对结果集中的数据进行访问,这些方法可以通过列索引或列名获得数据。ResultSet接口中常用的方法如表14-5所示。
ResultSet对象具有指向当前数据行的游标。最初游标位于第一行之前,每调用一次next()方法,游标会自动向下移一行,从而可以从上到下依次获取所有数据行。getXXX()方法用于对游标所指向的行的数据进行访问。在使用getXXX()方法取值时,数据库的字段数据类型要与Java的数据类型相匹配,例如,数据库中的整数字段对应Java数据类型中的int类型,此时使用getInt()方法来读取该字段中的数据。常用的SQL数据类型和Java数据类型之间的对应关系如表14-6所示。
我是田先生,一名热爱技术、热爱生活的Java程序员。专注分享java基础、dubbo源码、zookeeper, rabbitmq、mybatis源码、微服务springboot、集群、分布式、多线程等相关知识与实战经验。欢迎大家积极交流,共同探讨。欢迎关注我的公众号:t-j20120622(Java后端技术栈)。