JDBC batch批量Statement executeBatch 详细解释

JDBC提供了数据库batch处理的能力,在数据大批量操作(新增、删除等)的情况下能够大幅度提升系统的性能。我曾经接触的一个项目,在没有採用batch处理时,删除5万条数据大概要半个小时左右,后来对系统进行改造,採用了batch处理的方式,删除5万条数据基本上不会超过1分钟。看一段JDBC代码:

// 关闭自己主动运行

con.setAutoCommit(false);

Statement stmt = con.createStatement();

stmt.addBatch("INSERT INTO employees VALUES (1000, ‘Joe Jones‘)");

stmt.addBatch("INSERT INTO departments VALUES (260, ‘Shoe‘)");

stmt.addBatch("INSERT INTO emp_dept VALUES (1000, 260)");

// 提交一批要运行的更新命令

int[] updateCounts = stmt.executeBatch();

本例中禁用了自己主动运行模式,从而在调用 Statement.executeBatch() 时可以防止 JDBC 运行事务处理。禁用自己主动运行使得应用程序可以在错误发生及批处理中的某些命令不能运行时决定是否运行事务处理。因此,当进行批处理更新时,通常应该关闭自己主动运行。

在JDBC 2.0 中,Statement 对象可以记住可以一起提交运行的命令列表。创建语句时,与它关联的命令列表为空。Statement.addBatch() 方法为调用语句的命令列表加入一个元素。假设批处理中包括有试图返回结果集的命令,则当调用 Statement. executeBatch() 时,将抛出 SQLException。仅仅有 DDL 和 DML 命令(它们仅仅返回简单的更新计数)才干作为批处理的一部分来运行。假设应用程序决定不提交已经为某语句构

造的命令批处理,则能够调用方法 Statement.clearBatch()(以上没有显示)来又一次设置批处理。

Statement.executeBatch() 方法将把命令批处理提交给基本 DBMS 来运行。命令的运行将按照在批处理中的加入顺序来进行。ExecuteBatch() 为运行的命令返回更新计数数组。数组中相应于批处理中的每一个命令都包括了一项,而数组中各元素根据命令的运行顺序(这还是和命令的最初加入顺序同样)来排序。调用executeBatch() 将关闭发出调用的 Statement 对象的当前结果集(假设有一个结果集是打开的)。executeBatch() 返回后,将又一次将语句的内部批处理命令列表设置为空。

假设批处理中的某个命令无法正确运行,则 ExecuteBatch() 将抛出BatchUpdateException。能够调用BatchUpdateException.getUpdateCounts() 方法来为批处理中成功运行的命令返回更新计数的整型数组。由于当有第一个命令返回错误时,Statement.executeBatch() 就中止,并且这些命令是根据它们在批处理中的加入顺序而运行的。所以假设 BatchUpdateException.getUpdateCounts() 所返回的数组包括
N 个元素,这就意味着在调用 executeBatch() 时批处理中的前 N 个命令被成功运行。用PreparedStatement 能够象以下这样写代码:

// 关闭自己主动运行

con.setAutoCommit(false);

PreparedStatement stmt = con.prepareStatement("INSERT INTO employees VALUES (?, ?)");

stmt.setInt(1, 2000);

stmt.setString(2, "Kelly Kaufmann");

stmt.addBatch();

// 提交要运行的批处理

int[] updateCounts = stmt.executeBatch();

========================================

PrepareStatement 也是接口

PrepareStatement extends Statement

PrepareStatement 本身没有 int[] executeBatch() throws SQLException 方法

而是继承了Statement的方法,且它们都是接口没有实际实现方法,但Statement

接口对executeBatch()方法做了规范

/**

* Submits a batch of commands to the database for execution and

* if all commands execute successfully, returns an array of update counts.

每次提交一批命令到数据库中运行,假设全部的命令都成功运行了,那么返回一个

数组,这个数组是说明每条命令所影响的行数

* The <code>int</code> elements of the array that is returned are ordered

* to correspond to the commands in the batch, which are ordered

* according to the order in which they were added to the batch.

返回的数组中每一个整型值都是排过序的,它们的顺序和批量处理中的命令们是一致的,

命令的顺序是依照它们被加到批处理中的顺序一致。

* The elements in the array returned by the method <code>executeBatch</code>

* may be one of the following:

executeBatch方法返回的数组中的元素可能是以下几种情形之中的一个:

* <OL>

* <LI>A number greater than or equal to zero -- indicates that the

* command was processed successfully and is an update count giving the

* number of rows in the database that were affected by the command‘s

* execution

一个大于或等于零的数字,简单说来命令成功运行后就返回它所影响到的行的数目

* <LI>A value of <code>SUCCESS_NO_INFO</code> -- indicates that the command was

* processed successfully but that the number of rows affected is

* unknown

* The constant indicating that a batch statement executed successfully

* but that no count of the number of rows it affected is available.

int SUCCESS_NO_INFO = -2;

常量SUCCESS_NO_INFO代表的值=-2,也就是说命令运行成功了但命令影响到的行数

无法统计,是未知的,仅仅能返回SUCCESS_NO_INFO来说明命令运行情况。

* <P> * If one of the commands in a batch update fails to execute properly,

* this method throws a <code>BatchUpdateException</code>, and a JDBC

* driver may or may not continue to process the remaining commands in

* the batch.

假设批量处理时当中一个命令运行失败,则会抛出一个异常BatchUpdateException

JDBC驱动可能会停止剩余的命令,也可能继续运行剩余的命令。

* However, the driver‘s behavior must be consistent with a

* particular DBMS, either always continuing to process commands or never

* continuing to process commands.

无论如何,驱动要怎么做取决于数据库管理系统的细节,总是运行或总是不运行两者其一。

* If the driver continues processing

* after a failure, the array returned by the method

* <code>BatchUpdateException.getUpdateCounts</code>

* will contain as many elements as there are commands in the batch, and

* at least one of the elements will be the following:

发生失败后假设驱动继续运行,通过BatchUpdateException.getUpdateCounts()方法返回

的数组应该包含批处理中有的那些命令的结果,而且至少有一个元素的值是以下的情况:

* <P>

* <LI>A value of <code>EXECUTE_FAILED</code> -- indicates that the command failed

* to execute successfully and occurs only if a driver continues to

* process commands after a command fails

int EXECUTE_FAILED = -3;

指示命令没有成功运行的常量值EXECUTE_FAILED,而且仅仅有在命令出错后驱动继续运行的情况下才会出现,

假设出错后不再运行,则返回的结果中没有错误信息仅仅有那些被成功运行后的结果。

* </OL>

* <P> * A driver is not required to implement this method.

* The possible implementations and return values have been modified in

* the Java 2 SDK, Standard Edition, version 1.3 to

* accommodate the option of continuing to proccess commands in a batch

* update after a <code>BatchUpdateException</code> obejct has been thrown.

驱动不实现此方法,可能会出现的实现和返回值在Java 2 SDK,Standard Edition,

version 1.3 ,以适应批处理时抛出BatchUpdateException 异常后是继续运行还是

终止运行的选项。

* @return an array of update counts containing one element for each

* command in the batch. The elements of the array are ordered according

* to the order in which commands were added to the batch.

返回一个和加入命令时的顺序一样的数组结果

* @exception SQLException if a database access error occurs or the

* driver does not support batch statements. Throws {@link BatchUpdateException}

* (a subclass of <code>SQLException</code>) if one of the commands sent to the

* database fails to execute properly or attempts to return a result set.

* @since 1.3

*/

假设数据库訪问异常或驱动不支持批处理命令,或者假设一个命令发送到数据库时失败或尝试取得结果集

时失败,都会抛一个异常BatchUpdateException 它是SQLException的子类。

时间: 2024-08-26 20:00:09

JDBC batch批量Statement executeBatch 详细解释的相关文章

JDBC batch批处理Statement executeBatch 具体解释

JDBC提供了数据库batch处理的能力,在数据大批量操作(新增.删除等)的情况下能够大幅度提升系统的性能.我曾经接触的一个项目,在没有採用batch处理时,删除5万条数据大概要半个小时左右,后来对系统进行改造,採用了batch处理的方式,删除5万条数据基本上不会超过1分钟.看一段JDBC代码: // 关闭自己主动运行 con.setAutoCommit(false); Statement stmt = con.createStatement(); stmt.addBatch("INSERT I

Hibernate 抛出的 Could not execute JDBC batch update

异常堆栈 org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.

oracle事务处理及实例演示jdbc操作批量删除

事务 作为逻辑处理的基本单位,对于数据库操作来说由一条或者多条sql语句来构成.当然还有针对非数据库操作的,如在计算机中设置的还原点即是一个很好的应用. 对于事务的基本性质在另一篇中有所叙述:SQL 事务及实例演示 oracle和sql server在事务上区别 sql server中的事务一般分为隐式事务.显式事务.自动提交事务. 自动事务:对于sql server来说,当客户端提交一条sql语句时,这时候sql server都会自动启动一个事务:对于这样的事务,在执行完sql语句后会自动提交

oracle事务处理及实例演示jdbc操作批量删除 2014年8月11日

事务 作为逻辑处理的基本单位,对于数据库操作来说由一条或者多条sql语句来构成.当然还有针对非数据库操作的,如在计算机中设置的还原点即是一个很好的应用. 对于事务的基本性质在另一篇中有所叙述:SQL 事务及实例演示 oracle和sql server在事务上区别 sql server中的事务一般分为隐式事务.显式事务.自动提交事务. 自动事务:对于sql server来说,当客户端提交一条sql语句时,这时候sql server都会自动启动一个事务:对于这样的事务,在执行完sql语句后会自动提交

sping异常记录----Could not execute JDBC batch update; nested exception is org.hibernate.excepti

今天在练习如何SSH中进行单元测试的时候出现下列异常: org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update at org.springframe

SSM:spring+springmvc+mybatis框架中的XML配置文件功能详细解释

SSM:spring+springmvc+mybatis框架中的XML配置文件功能详细解释 2016-04-14 23:40 13030人阅读 评论(2) 收藏 举报 分类: SSM(7) 这几天一直在整合SSM框架,虽然网上有很多已经整合好的,但是对于里面的配置文件并没有进行过多的说明,很多人知其然不知其所以然,经过几天的搜索和整理,今天总算对其中的XML配置文件有了一定的了解,所以拿出来一起分享一下,希望有不足的地方大家批评指正~~~ 首先   这篇文章暂时只对框架中所要用到的配置文件进行解

hibernate 级联删除报更新失败的问题(org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update)

首先hibernate级联删除的前提是,首先需要在映射文件中配置,配置多表之间的关联关系: 下面以部门表(Dept)和员工表(Emp)为例: 1.在Emp.hbm.xml映射文件中配置many-to-one关系 1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http:/

Android中多线程编程(四)AsyncTask类的详细解释(附源码)

Android中多线程编程中AsyncTask类的详细解释 1.Android单线程模型 2.耗时操作放在非主线程中执行 Android主线程和子线程之间的通信封装类:AsyncTask类 1.子线程中更新UI 2.封装.简化异步操作. 3.AsyncTask机制:底层是通过线程池来工作的,当一个线程没有执行完毕,后边的线程是无法执行的.必须等前边的线程执行完毕后,后边的线程才能执行. AsyncTask类使用注意事项: 1.在UI线程中创建AsyncTask的实例 2.必须在UI线程中调用As

我对CONTAINING_RECORD宏的详细解释

宏CONTAINING_RECORD的用处其实还是相当大的, 而且很是方便, 它的主要作用是: 根据结构体中的某成员的指针来推算出该结构体的指针! 下面从一个简单的例子开始说起: 我们定义一个结构体, 同时类型化: typedef struct{ int a; int b; int c; }ss; 这是一个很简单的结构体, 没什么特殊的, 稍微分析下该结构体: 结构体的大小(字节):4+4+4=12字节 成员a的偏移:0 成员b的偏移:4 成员c的偏移:8 我们用ss来定义一个变量: ss s