1、本章学习目标:了解JDBC概念以及驱动类型 掌握使用JDBC连接MySQL数据库的基本步骤 掌握数据库环境的搭建 掌握使用JDBC访问数据库的步骤 掌握使用Java API操作数据库 掌握数据库事务的使用第十四章第十四章 JDBCJDBC与与MySQLMySQL编程编程第第1 1节节partJDBC基础 通过使用JDBC,Java程序可以轻松地操作各种主流数据库,例如,Oracle、MS SQL Server、MySQL等。由于Java语言本身的跨平台性,所以使用JDBC编写的程序不仅可以实现跨数据库,还具有跨平台性和可移植性。使用JDBC访问数据库具有操作简单、获取方便且安全可靠等优势。J
2、D B C 基 础本节概述 JDBC(Java Database Connectivity,Java数据库连接)是一种执行SQL语句的Java API。程序可以通过JDBC API连接到关系数据库,并使用SQL结构化语言来完成对数据库的增、删、改、查等操作。与其他数据库编程语言相比,JDBC为数据开发者提供了标准的API,使用JDBC开发的数据库应用程序可以访问不同的数据库,并在不同平台上运行,既可以在Windows平台上运行,也可以在UNIX平台上运行。JDBC程序访问不同的数据库时,需要数据库厂商提供相应的驱动程序。通过JDBC驱动程序的转换,使得相同的代码在访问不同的数据库时运行良好。J
3、DBC驱动示意图如图14.1所示。14.1.1J D B C 简 介JDBC简介 JDBC应用程序可以对数据库进行访问和操作,JDBC访问数据库时主要完成以下工作:建立与数据库的连接;执行SQL语句;获取执行结果。数据库驱动程序是JDBC程序和数据库之间的转换层,数据库驱动程序负责将JDBC调用映射成特定的数据库调用,JDBC访问示意图如图14.2所示。14.1.2J D B C 驱 动JDBC驱动 当今市场上主流数据库都提供了JDBC驱动程序,甚至一些流行的数据库还提供了多种不同版本的JDBC驱动程序。JDBC驱动程序有以下4种类型:JDBC-ODBC桥:是最早实现的JDBC驱动程序,主要目
4、的是快速推广JDBC。ODBC(Open Database Connectivity,开放数据库连接)是通过一组通用的API访问不同的数据库管理系统,也需要各数据库厂商提供相应的驱动程序,而ODBC则对这些驱动程序进行管理。JDBC-ODBC桥驱动是将JDBC API映射到ODBC API,驱动速度很慢,只适用于访问没有其他JDBC驱动的数据库。由于Java语言的广泛应用,所有数据库厂商都提供了JDBC驱动,因此在Java 8中不再支持JDBC-ODBC数据访问方式。J D B C 驱 动14.1.2 本地API驱动:直接将JDBC API映射成数据库特定的客户端API,包含特定的数据库本地代
5、码,用于访问特定数据库的客户端。本地API驱动比起JDBC-ODBC桥执行效率要高,但是仍然需要在客户端加载数据库厂商提供的代码库,不适合基于网络的应用。本地API驱动虽然速度有所提升,但相对后面两种JDBC驱动还是不够高。网络协议驱动:将JDBC调用翻译成中间件供应商的协议,然后再由中间件服务器翻译成数据库访问协议。网络协议驱动是基于服务器的,不需要在客户端加载数据库厂商提供的代码库,且执行效率比较好,便于维护和升级。本地协议驱动:是纯Java编写的,可以直接连接到数据库。本地协议驱动不需要将JDBC的调用传给ODBC,或本地数据库接口,或中间层服务器,因此执行效率非常高;而且根本不需要在客
6、户端或服务器装载任何软件或驱动。本地协议驱动是智能的,能够知道数据库使用的底层协议,是目前最流行的JDBC驱动。通常JDBC访问数据库时建议使用第4种本地协议驱动,该驱动使用纯Java编写,且避开了本地代码,减少了应用开发的复杂性,降低了产生冲突和出错的可能。J D B C 驱 动14.1.2 JDBC API提供了一组用于与数据库进行通信的接口和类,这些接口和类都定义在java.sql包中,常用的接口和类如表14-1所示。14.1.3JDBC APIJDBC API 需要注意的是:使用JDBC API中的类或接口访问数据库时,容易引发SQLException异常,SQLException异常
7、类是检查型异常,需要放在trycatch语句中进行异常处理,SQLException是JDBC中其他异常类型的基础。1.1.DriverManagerDriverManager类类 DriverManager是数据库驱动管理类,用于管理一组JDBC驱动程序的基本服务。应用程序和数据库之间可以通过DriverManager建立连接,其常用的静态方法如表14-2所示。JDBC API14.1.3 2.Connection 2.Connection接口接口 Connection接口用于连接数据库,每个Connection对象代表一个数据库连接会话,要想访问数据库,必须先获得数据库连接。一个应用程序可
8、与单个数据库建立一个或多个连接,也可以与多个数据库建立连接。通过DriverManager类的getConnection()方法可以返回一个Connection对象,该对象中提供了创建SQL语句的方法,以完成基本的SQL操作,同时为数据库事务提供了提交和回滚的方法。Connection接口中常用的方法如表14-3所示。JDBC API14.1.3 3.Statement 3.Statement接口接口 Statement接口一般用于执行SQL语句。在JDBC中要执行SQL查询语句的方式有一般查询(Statement)、参数查询(PreparedStatement)和存储过程(CallableS
9、tatement)三种方式。Connection接口中提供的createStatement()、prepareStatement()和prepareCall()方法分别返回一个Statement对象,PreparedStatement对象和CallableStatement对象。Statement、PreparedStatement和CallableStatement三个接口具有继承关系,其中PreparedStatement是Statement的子接口,而CallableStatement又是PreparedStatement的子接口。Statement接口的主要功能是将SQL语句传送给数据
10、库,并返回SQL语句的执行结果。Statement提交的SQL语句是静态的,不需要接收任何参数,SQL语句可以包含以下三种类型的语句:SELECT查询语句;DML语句,如INSERT、UPDATE或DELETE;DDL语句,如CREATE TABLE和DROP TABLE。JDBC API14.1.3 Statement接口中常用的方法及功能如表14-4所示。JDBC API 需要注意的是:closeOnCompletion()和isCloseOnCompletion()方法是从Java 7开始新增的方法,executeLargeUpdate()方法是从Java 8开始新增的方法,在开发过程中
11、使用这几个方法时需要注意JDK的版本。考虑到目前应用程序所处理的数据量越来越大,使用executeLargeUpdate()方法具有更好的适应性,但目前有的数据库驱动暂不支持该方法,例如MySQL驱动。14.1.3 4.4.ResultSetResultSet接口接口 ResultSet接口用于封装结果集对象,该对象包含访问查询结果的方法。使用Statement中的executeQuery()方法可以返回一个ResultSet结果集的对象,该对象封装了所有符合查询条件的记录。ResultSet具有指向当前数据行的游标,并提供了许多方法来操作结果集中的游标,同时还提供了一套getXXX()方法对
12、结果集中的数据进行访问,这些方法可以通过列索引或列名获得数据。ResultSet接口中常用的方法如表14-5所示。JDBC API14.1.3 ResultSet对象具有指向当前数据行的游标。最初游标位于第一行之前,每调用一次next()方法,游标会自动向下移一行,从而可以从上到下依次获取所有数据行。getXXX()方法用于对游标所指向的行的数据进行访问。在使用getXXX()方法取值时,数据库的字段数据类型要与Java的数据类型相匹配,例如,数据库中的整数字段对应Java数据类型中的int类型,此时使用getInt()方法来读取该字段中的数据。常用的SQL数据类型和Java数据类型之间的对应
13、关系如表14-6所示。JDBC API14.1.3第第2 2节节part数据库环境搭建14.2.1创建数据库表 本章JDBC数据库访问基于MySQL数据库,因此所有的代码及环境都是基于MySQL数据库的。在进行数据库访问操作之前,需要先创建数据库和表并录入测试数据。在root用户下创建student数据库,并在该库下创建t_user表,并添加测试数据,其SQL代码如下所示。创建数据库表创建数据库表 【代码14.1】student.sql CREATE DATABASE student;CREATE TABLE t_user(Id int(11)NOT NULL AUTO_INCREMENT,s
14、id varchar(20)DEFAULT NULL,name varchar(20)DEFAULT NULL,password varchar(20)DEFAULT NULL,sex varchar(20)DEFAULT NULL,major varchar(20)DEFAULT NULL,hobby varchar(20)DEFAULT NULL,PRIMARY KEY(Id);#添加测试数据 INSERT INTO t_user VALUES(19,159110909,向守超,111,男,物联网工程,篮球 足球),(20,159110901,张恒,123,男,物联网工程,篮球 足球);创
15、建完库student、表t_user和添加完数据以后,在MySQL-Front图形化界面工具中打开,其表中的数据如图14.3所示。14.2.2设置MySQL驱动类 Java项目在访问MySQL数据库时,需要在项目中设置MySQL驱动类路径,即将MySQL数据库所提供的JDBC驱动程序(mysql-connector-java-5.1.12-bin0)导入到工程中。mysql-connector-java-5.1.12-bin.jar驱动文件可在网络上直接下载,当然也可以下载其他的版本。配置MySQL数据库驱动程序有两种方法:一种方法是将驱动程序配置到CLASSPATH中,与配置JDK的环境变量
16、类似,这种方法的配置将对本机中所有创建的项目起作用,但程序员一般不用这种方法;第二种方法是在基础开发工具Eclipse中选中项目,右键单击,在弹出的快捷菜单中选择“PropertiesJava Build PathlibrariesAdd External JARs”命令,在弹出的对话框中,选择mysql-connector-java-5.1.12-bin.jar文件。如图14.4所示。设置MySQL驱动类设置MySQL驱动类 设置完MySQL数据库驱动类路径之后,项目的目录如图14.5所,Referenced Libraries文件夹中的mysql-connector-java-5.1.12
17、-bin.jar表示对该jar包的引用。14.2.2第第3 3节节part数据库访问使用JDBC访问数据库的步骤:加载数据库驱动;建立数据连接;创建Statement对象;执行SQL语句;访问结果集;数据库访问本节概述14.3.1加载数据库驱动 通常使用Class类的forName()静态方法来加载数据库的驱动,其语法格式如下所示:/加载驱动 Class.forName(数据库驱动类名);例如:Class.forName(com.mysql.jdbc.Driver);/加载MySQL驱动 需要注意的是:不同的数据库其数据库驱动类是不同的,例如:Oracle数据库的驱动类是oracle.jdbc
18、.driver.OracleDriver,而MySQL的数据库驱动类是com.mysql.jdbc.Driver。数据库厂商在提供数据库驱动(通常是一个或几个jar文件)时,会有相应的文档说明。加载数据库驱动14.3.2建立数据库连接 在使用JDBC操作数据库之前,需要先创建一个数据库连接,使用DriverManager类的getConnection()静态方法来获取数据库连接对象,其语法格式如下所示:DriverManager.getConnection(String url,String user,String pass);其中,getConnection()方法有三个参数,具体如下:ur
19、l:数据库连接字符串,遵循的格式是“jdbc:驱动:其他”,不同的数据库连接的URL也有所不同。user:连接数据库的用户名;pass:密码。建立数据库连接14.3.2建立数据库连接例如,访问MySQL数据库的URL连接字符串jdbc:mysql:/127.0.0.1:3306/student在上面的URL连接字符串中:jdbc:mysql是协议名称“127.0.0.1”是本机服务器IP地址,也可以使用“localhost”;“3306”是MySQL数据库的端口号;“student”是数据库实例名。例如:获取MySQL数据库连接对象Class.forName(com.mysql.jdbc.Dr
20、iver);Connection conn=DriverManager.getConnection(jdbc:mysql:/127.0.0.1:3306/student,/URL连接字符串root,/用户名root);/密码14.3.3创建Statement对象 对数据库进行操作或访问时,需要使用SQL语句。在Java语言中,SQL语句是通过Statement对象进行封装后,发送给数据库。Statement对象不是通过Statement类直接创建的,而是通过Connection对象所提供的方法来创建各种Statement对象。通过Connection对象来获得Statement的方法有以下三种
21、:createStatement()方法:创建一个基本的Statement对象;prepareStatement(String sql)方法:根据参数化的SQL语句创建一个预编译的PreparedStatement对象;prepareCall(String sql)方法:根据SQL语句来创建一个CallableStatement对象,用于调用数据库的存储过程。例如:/创建Statment对象 Statement stmt=conn.createStatement();创建Statement对象14.3.4执行SQL语句 获取Statement对象之后,就可以调用该对象的不同方法来执行SQL语句
22、。所有的Statement都有三种执行SQL语句的方法,具体使用哪一种方法由SQL语句产生的结果来决定:executeQuery()方法:只能执行查询语句,例如SELECT语句,用于产生单个结果集;executeUpdate()和executeLargeUpdate()方法:用于执行DML和DDL语句,执行DML(INSERT、UPDATE或DELETE语句)时返回受SQL语句所影响的行数(整数值),而执行DDL语句(CREATE TABLE、DROP TABLE等)返回值总为0;execute()方法:可以执行任何SQL语句,此方法比较特殊,也比较麻烦,返回结果为多个结果集、多个更新计数或二
23、者的组合。通常不建议使用该方法,只有在不知道执行SQL语句会产生什么结果或可能有多种类型结果的情况下才会使用。如果SQL语句运行后能产生结果集,Statement对象则将结果集封装成ResultSet对象并返回。下述代码调用Statement对象的executeQuery()方法来执行SQL查询语句,并返回一个ResultSet结果集对象。例如:执行SQL查询语句并返回结果集ResultSet rs=smt.executeQuery(SELECT*FROM t_user);执行SQL语句14.3.5访问结果集 SQL的查询结果使用ResultSet封装,ResultSet结果集包含了满足SQL
24、查询条件的所有的行,使用getXXX()方法对结果集中的数据进行访问。当使用getXXX()方法访问结果集中的数据时,可通过列索引或列名来获取游标所指行中的列数据,其语法格式如下;getXXX(列索引)或 getXXX(“列名”)例如:循环输出结果集中第三列数据。while(rs.next()System.out.println(rs.getString(3);或 while(rs.next()System.out.println(rs.getString(name);访问结果集访问结果集 需要注意的是:在使用getXXX()方法来获得数据库表中的对应字段的数据时,尽可能使用序列号参数,这样可
25、以提高效率。除Blob类型外,其他任意类型的字段都可以通过getString()方法来获取,因为所有数据类型都可以自动转换成字符串。当数据库操作执行完毕或退出应用前,需将数据库访问过程中建立的对象按顺序关闭,防止系统资源浪费。关闭的次序是:关闭结果集:rs.close();关闭Statement对象:stmt.close();关闭连接:conn.close();下述案例用于示例访问数据库的一般步骤,代码如下所示。14.3.5访问结果集【代码14.2】ConnectionExample.javapackage com;import java.sql.Connection;import java.
26、sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class ConnectionExample public static void main(String args)try/加载驱动Class.forName(com.mysql.jdbc.Driver);/建立数据库连接Connection conn=DriverManager.getConnection(jdbc:mysql:/127.0.0.1:3306/student,ro
27、ot,root);System.out.println(连接成功!);/创建Statment对象Statement stmt=conn.createStatement();/获取查询结果集ResultSet rs=stmt.executeQuery(SELECT*FROM t_user);14.3.5访问结果集System.out.println(查询成功!);/访问结果集中的数据while(rs.next()System.out.println(rs.getString(1)+rs.getString(name);/关闭结果集rs.close();/关闭载体stmt.close();/关闭连
28、接conn.close();catch(ClassNotFoundException e)e.printStackTrace();catch(SQLException e)e.printStackTrace();14.3.5访问结果集 上述代码按照访问数据库的一般步骤编写。通过Class.forName()方法加载MySQL数据库驱动;调用DriverManager.getConnection()方法来建立MySQL数据库连接,在获取连接时需要指明数据库连接的URL、用户名和密码;通过连接对象的createStatement()方法来获取Statement对象,调用Statement对象的ex
29、ecuteQuery()方法执行SQL语句;调用ResultSet结果集对象的next()方法将游标移动到下一条记录,再通过getXXX()方法来获取指定列中的数据;最后调用close()方法关闭所有创建的对象。程序运行结果如下所示:连接成功!查询成功!19 向守超 20 张恒14.3.5第第4 4节节part操作数据库 JDBC不仅可以执行数据库查询,还可以执行DDL、DML等SQL语句,以便最大限度地操作数据库。操作数据库本节概述14.4.1execute()方法 Statement接口的execute()方法几乎可以执行任何SQL语句,如果不清楚SQL语句的类型,则只能通过使用execu
30、te()方法来执行SQL语句。使用execute()方法执行SQL语句的返回值是boolean值,表明执行该SQL语句是否返回了ResultSet对象:当返回值为true时,可以使用Statement的getResultSet()方法,来获取execute()方法执行SQL查询语句所返回的ResultSet对象;当返回值为false时,可以使用getUpdateCount()方法,来获取execute()方法执行DML语句所影响的行数。下述案例示例了Statement对象的execute()方法的使用,代码如下所示。execute()方法【代码14.3】ExecuteExample.javap
31、ackage com;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.Statement;public class ExecuteExample private String driver=com.mysql.jdbc.Driver;private String url=jdbc:mysql:/127.0.0.1:3306/student;private String user=root;private String pass=root;publ
32、ic void executeSql(String sql)throws Exception/加载驱动Class.forName(driver);try(/获取数据库连接Connection conn=DriverManager.getConnection(url,user,pass);/使用Connection来创建一个Statement对象Statement stmt=conn.createStatement()execute()方法14.4.1/执行SQL,返回boolean值表示是否包含ResultSetboolean hasResultSet=stmt.execute(sql);/如
33、果执行后有ResultSet结果集if(hasResultSet)try(/获取结果集ResultSet rs=stmt.getResultSet()/迭代输出ResultSet对象while(rs.next()/依次输出第1列的值System.out.print(rs.getString(1)+t);System.out.println();else System.out.println(该SQL语句影响的记录有+stmt.getUpdateCount()+条);execute()方法14.4.1public static void main(String args)throws Excep
34、tion ExecuteExample executeObj=new ExecuteExample();System.out.println(-执行建表的DDL语句-);executeObj.executeSql(create table my_test+(test_id int primary key,test_name varchar(25);System.out.println(-执行插入数据的DML语句-);executeObj.executeSql(insert into my_test(test_id,test_name)+select id,name from t_user);S
35、ystem.out.println(-执行查询数据的查询语句-);executeObj.executeSql(select test_name from my_test);System.out.println(-执行删除表的DDL语句-);executeObj.executeSql(drop table my_test);execute()方法14.4.1 上述代码先定义了一个executeSql()方法,用于执行不同的SQL语句,当执行结果有ResultSet结果集时,则循环输出结果集中第3列的信息;否则输出该SQL语句所影响的记录条数。在main()方法中,调用executeSql()方法
36、,分别执行建表、插入、查询和删除表四个SQL语句。程序运行结果如下:-执行建表的DDL语句-该SQL语句影响的记录有0条 -执行插入数据的DML语句-该SQL语句影响的记录有2条 -执行查询数据的查询语句-向守超张恒 -执行删除表的DDL语句-该SQL语句影响的记录有0条 需要注意的是:使用Statement执行DDL和DML语句的步骤与执行普通查询语句的步骤基本相似。区别在于执行DDL语句后返回值为0,而执行了DML语句后返回值为受影响的行数。execute()方法14.4.114.4.2executeUpdate()方法 executeUpdate()和executeLargeUpdate
37、()方法用于执行DDL和DML语句,其中executeLargeUpdate()方法是Java 8新增的方法,是增强版的executeUpdate()方法。executeLargeUpdate()方法的返回值类型为long,当DML语句影响的记录超过Integer.MAX_VALUE时,建议使用该方法。下述案例示例了Statement对象的executeUpdate()方法的使用,目前MySQL数据库驱动暂不支持executeLargeUpdate()方法功能。代码如下所示。executeUpdate()方法executeUpdate()方法【代码14.4】ExecuteUpdateExamp
38、le.javapackage com;import java.sql.Connection;import java.sql.DriverManager;import java.sql.Statement;public class ExecuteUpdateExample private String driver=com.mysql.jdbc.Driver;private String url=jdbc:mysql:/127.0.0.1:3306/student;private String user=root;private String pass=root;public void crea
39、teTable(String sql)throws Exception/加载驱动Class.forName(driver);try(/获取数据库连接Connection conn=DriverManager.getConnection(url,user,pass);/使用Connection来创建一个Statment对象Statement stmt=conn.createStatement()/执行DDL,创建数据表stmt.executeUpdate(sql);14.4.2executeUpdate()方法public long insertData(String sql)throws Ex
40、ception/加载驱动Class.forName(driver);try(/获取数据库连接Connection conn=DriverManager.getConnection(url,user,pass);/使用Connection来创建一个Statment对象Statement stmt=conn.createStatement()/执行DML,返回受影响的记录条数return stmt.executeUpdate(sql);public static void main(String args)throws Exception ExecuteUpdateExample elud=new
41、 ExecuteUpdateExample();elud.createTable(create table my_test1+(test_id int primary key,test_name varchar(25);System.out.println(-建表成功-);long result=elud.insertData(insert into my_test1(test_id,test_name)select id,name from t_user);System.out.println(-系统中共有+result+条记录受影响-);14.4.2executeUpdate()方法 上述
42、代码定义了createTable()方法来创建表,insertData()方法用于插入数据,不管是执行DDL语句还是执行DML语句,最终都是通过调用Statement对象的executeUpdate()方法来实现的。运行该程序,结果如下所示:-建表成功-系统中共有2条记录受影响-14.4.214.4.3PreparedStatement接口 PreparedStatement接口继承Statement接口,该接口具有以下两个特点:PreparedStatement对象中所包含的SQL语句将进行预编译,当需要多次执行同一条SQL语句时,直接执行预先编译好的语句,其执行速度比Statement对象
43、快;PreparedStatement可用于执行动态的SQL语句,即在SQL语句中提供参数,大大提高了程序的灵活性和执行效率。动态SQL语句使用“?”作为动态参数的占位符,示例如下所示。例如:参数化的动态SQL语句,创建PreparedStatement对象 String insertSql=INSERT INTO userdetails(sid,name,password,sex)VALUES(?,?,?,?);PreparedStatement pstmt=conn.prepareStatement(insertSql);PreparedStatement接口PreparedStateme
44、nt接口 在执行带参数的SQL语句前,必须对“?”占位符参数进行赋值。PreparedStatement接口中提供了大量的setXXX()方法,通过占位符的索引完成对输入参数的赋值,根据参数的类型来选择对应的setXXX()方法,PreparedStatement接口中提供的常用setXXX()方法如表14-7所示。14.4.3PreparedStatement接口下述案例示例了PreparedStatement的使用,代码如下所示。【代码14.5】PreparedStatementExample.javapackage com;import java.sql.Connection;impor
45、t java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.SQLException;public class PreparedStatementExample public static void main(String args)try/加载oracle驱动Class.forName(com.mysql.jdbc.Driver);/建立数据库连接Connection conn=DriverManager.getConnection(jdbc:mysql:/127.0.0.1:3306/student,
46、root,root);/定义带参数的sql语句String insertSql=INSERT INTO t_user(sid,name,password,sex)+VALUES(?,?,?,?);/创建PreparedStatement对象PreparedStatement pstmt=conn.prepareStatement(insertSql);14.4.3PreparedStatement接口/使用setXXX()方法对参数赋值pstmt.setInt(1,7);pstmt.setString(2,Tom);pstmt.setString(3,123456);pstmt.setByte
47、(4,(byte)1);/执行int result=pstmt.executeUpdate();System.out.println(插入+result+行!);/关闭载体pstmt.close();/关闭连接conn.close();catch(ClassNotFoundException e)e.printStackTrace();catch(SQLException e)e.printStackTrace();14.4.3PreparedStatement接口 上述代码先定义一个带参数的SQL语句;再使用该语句来创建一个PreparedStatement对象;然后调用PreparedSt
48、atement对象的setXXX()方法对参数进行赋值,并调用PreparedStatement对象的executeUpdate()方法来执行SQL语句。运行该程序,结果如下所示:插入1行!14.4.3第第5 5节节part事务处理 事务是保证底层数据完整的重要手段,对于任何数据库都是非常重要的。事务是由一步或几步数据库操作序列组成的逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行。事务具有ACID四个特性:原子性(Atomicity):事务是应用中的最小执行单位,就如原子是自然界的最小颗粒一样,具有不可再分的特性。事务中的全部操作要么全部完成,要么都不执行。一致性(Consistenc
49、y):事务执行之前和执行之后,数据库都必须处于一致性状态,即从执行前的一个一致状态变为另一个一致性的状态。隔离性(Isolation):各个事务的执行互不干扰,任意一个事务的内部操作对其他并发事务都是隔离的,即并发执行的事务之间不能看到对方的中间状态,并发事务之间是互不影响的。持久性(Durability):事务一旦提交,对数据库所做的任何改变都永久地记录到存储器中,即保存到物理数据库中,不被丢失。事务处理事务处理 事务处理过程中会涉及到事务的提交、中止和回滚三个概念。“事务提交”是指成功执行完毕事务,事务提交又分显示提交和自动提交两种;“事务中止”是指未能成功完成事务,执行中断;“事务回滚”
50、对于中止事务所造成的变更需要进行撤销处理,即事务所做的修改全部失效,数据库返回到事务执行前的状态,事务回滚也有显示回滚和自动回滚两种。JDBC对事务操作提供了支持,其事务支持由Connection提供。JDBC的事务操作步骤如下:开启事务;执行任意多条DML语句;执行成功,则提交事务;执行失败,则回滚事务;Connection在默认情况下会自动提交,即事务是关闭的。此种情况下,一条SQL语句更新成功后,系统会立即调用commit()方法提交到数据库,而无法对其进行rollback回滚操作。事务处理 使用Connection对象的setAutoCommit()方法可开启或者关闭自动提交模式,其参