Java回顾之JDBC(1)(3)
预处理以及批处理
预处理和批处理都是用来提升系统性能的方式,一种是利用数据库的缓存机制,一种是利用数据库一次执行多条语句的方式。
预处理
数据库服务器接收到Statement后,一般会解析Statement、分析是否有语法错误、定制最优的执行计划,这个过程可能会降低系统的性能。一般的数据库服务器都这对这种情况,设计了缓存机制,当数据库接收到指令时,如果缓存中已经存在,那么就不再解析,而是直接运行。
这里相同的指令是指sql语句完全一样,包括大小写。
JDBC使用PreparedStatement来完成预处理:
预处理示例执行结果如下:
=====Insert a single record by PreparedStatement===== ID:1; NAME=Zhang San ID:2; NAME=TEST ID:5; NAME=Lei Feng
批处理
批处理是利用数据库一次执行多条语句的机制来提升性能,这样可以避免多次建立连接带来的性能损失。
批处理使用Statement的addBatch来添加指令,使用executeBatch方法来一次执行多条指令:
批处理示例执行结果如下:
=====Insert multiple records by Statement & Batch===== ID:1; NAME=Zhang San ID:2; NAME=TEST ID:5; NAME=Lei Feng ID:6; NAME=Xiao Zhang ID:7; NAME=Xiao Liu ID:8; NAME=Xiao Zhao
预处理和批处理相结合
我们可以把预处理和批处理结合起来,利用数据库的缓存机制,一次执行多条语句:
预处理和批处理相结合的示例执行结果如下:
=====Insert multiple records by PreparedStatement & Batch===== ID:1; NAME=Zhang San ID:2; NAME=TEST ID:5; NAME=Lei Feng ID:9; NAME=Xiao Zhang ID:10; NAME=Xiao Liu ID:11; NAME=Xiao Zhao
数据库事务
谈到数据库开发,事务是一个不可回避的话题,JDBC默认情况下,是每一步都自动提交的,我们可以通过设置 connection.setAutoCommit(false)的方式来强制关闭自动提交,然后通过connection.commit()和 connection.rollback()来实现事务提交和回滚。
简单的数据库事务
下面是一个简单的数据库事务的示例:
简单的数据库事务示例连续执行上述方法两次,我们可以得出下面的结果:
=====Simple Transaction test===== ID:1; NAME=Zhang San ID:2; NAME=TEST ID:5; NAME=Lei Feng ID:12; NAME=Xiao Li =====Simple Transaction test===== ID:1; NAME=Zhang San ID:2; NAME=TEST ID:5; NAME=Lei Feng ID:12; NAME=Xiao Li com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Duplicate entry '12' for key 'PRIMARY' at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:931) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2870) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665) at com.mysql.jdbc.Connection.execSQL(Connection.java:3170) at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1316) at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1235) at sample.jdbc.mysql.ResultSetSample.transactionTest1(ResultSetSample.java:154) at sample.jdbc.mysql.ResultSetSample.main(ResultSetSample.java:17)
可以看到,第一次调用时,操作成功,事务提交,向user表中插入了一条记录;第二次调用时,发生主键冲突异常,事务回滚。
带有SavePoint的事务
当我们的事务操作中包含多个处理,但我们有时希望一些操作完成后可以先提交,这样可以避免整个事务的回滚。JDBC使用SavePoint来实现这一点。
带有SavePoint的事务示例执行结果如下:
=====Simple Transaction test===== com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Duplicate entry '13' for key 'PRIMARY' at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:931) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2870) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665) at com.mysql.jdbc.Connection.execSQL(Connection.java:3170) at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1316) at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1235) at sample.jdbc.mysql.ResultSetSample.transactionTest2(ResultSetSample.java:185) at sample.jdbc.mysql.ResultSetSample.main(ResultSetSample.java:18) ID:1; NAME=Zhang San ID:2; NAME=TEST ID:5; NAME=Lei Feng ID:13; NAME=Xiao Li ID:14; NAME=Xiao Wang
可以看到最终事务报出了主键冲突异常,事务回滚,但是依然向数据库中插入了ID为13和14的记录。
另外,在确定SavePoint后,ID为15的记录并没有被插入,它是通过事务进行了回滚。
原文链接:http://www.cnblogs.com/wing011203/archive/2013/05/12/3073838.html
用户点评