使用JDBC对数据库实现批处理操作
本篇讲述如何使用JDBC对数据库实现批处理操作。很多时候单条SQL命令不能满足我们的需求,我们需要对数据库一次实现很多操作,需要发送一批SQL命令给数据库执行。
而JDBC也提供了相应的方法给我们实现批处理操作。分别使用Statement对象或者PreparedStatement对象。这两种方式分别有着不同的运用场景:
⑴ 使用Statement对象
优点:能发送多条不同操作类型的SQL命令,也就是说在这发送的一批SQL语句中可以有各种增删改查命令。
缺点:虽然能发送多条不同操作类型的SQL命令,但没有预编译,因此在数据库这一批中的每条SQL都需要编译和执行两个步骤。
⑵ 使用PreparedStatement对象
优点:发送的是预编译后的SQL语句,数据库对这一批SQL命令只需要执行这一个步骤即可。
缺点:只能发送多条相同操作类型,但占位符参数可以不同的SQL命令。也就是说这一批SQL要么是更新,要么是添加等等。稍后会介绍。
操作:
① 无论是Statement对象还是PreparedStatement对象,内部都含有一个List集合来保存一批多条SQL语句。两个对象都使用addBatch方法来添加每一条SQL语句(Statement使用有参的addBatch方法,PreparedStatement使用无参的addBatch方法,后面会介绍到)。
② 当Statement对象或PreparedStatement对象都添加完一批SQL之后,都使用executeBatch()方法来使数据库执行批处理,完成后返回一个整型数组int[],该整型数组中的元素的顺序对应于提交给Statement对象或PreparedStatement对象的SQL语句顺序,如果返回的是大于或等于0的数则表示成功处理并给出执行所影响的行数。当然改数组还会是别的内容,具体请看相关API文档:

③ 在每次执行完executeBatch()方法后,请一定要再调用clearBatch()方法,将清空Statement对象或PreparedStatement对象中List集合保存的SQL命令列表。
④ 在使用批处理操作时,且不可一次执行过多SQL命令,例如几千万次,尤其是在使用PreparedStatement对象的方式情况下,极容易造成程序内存溢出。对于要执行过多次的操作,请将执行次数再分成各小批分别执行。
下面分别以使用Statement对象和使用PreparedStatement对象的两个例子来说明两种批处理方式的不同之处。
例1:使用Statement对象进行批处理
在这个案例中,我使用Statement对象进行批处理操作同时包含了插入和修改两种操作,如果该批处理成功执行就说明了使用Statement对象能进行不同类型的数据库操作。
创建数据库和表:
create database jdbcdemo;
use jdbcdemo;
create table batchtest (
id int primary key,
name varchar(40)
)
创建工程,在工程中导入数据库连接驱动的jar包。在【src】目录下新建一个database.properties文件,内容如下:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcdemo
username=root
password=root
构建JDBC的工具类,包括注册驱动,获取连接,释放资源和连接等,这部分同《JDBC操作数据库的学习(2)》中相同,此处略。
使用Statement对象进行批处理操作:
public void statementbatch() throws SQLException {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
st = conn.createStatement();
String sql1 = "insert into batchtest(id,name) values(1,'Ding')";
String sql2 = "update batchtest set name='LRR' where id=1 ";
st.addBatch(sql1);
st.addBatch(sql2);
st.executeBatch();
st.clearBatch();
}finally{
JdbcUtils.release(conn, st, rs);
}
}
查看数据库执行情况:

第一条SQL是插入命令,插入一个id列为1,name列为“Ding”的行数据项;第二条SQL是修改命令,将id列为1的行数据项的name列修改为“LRR”。
例2:使用PreparedStatement对象进行批处理
因为PreparedStatement对象只能执行相同的操作类型,因此在该案例中我向数据库中执行插入的批处理SQL。
创建数据库和表(与例1相同):
create database jdbcdemo;
use jdbcdemo;
create table batchtest (
id int primary key,
name varchar(40)
)
创建工程,在工程中导入数据库连接驱动的jar包。在【src】目录下新建一个database.properties文件,内容如下:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcdemo
username=root
password=root
构建JDBC的工具类,包括注册驱动,获取连接,释放资源和连接等,这部分同《JDBC操作数据库的学习(2)》中相同,此处略。
使用PreparedStatement对象进行批处理操作:
public void preparedStatementBatch() throws SQLException {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
String sql = "insert into batchtest(id,name) values(?,?)";
st = conn.prepareStatement(sql);
st.setInt(1, 1); //设置id列
st.setString(2, "Ding"); //设置name列
st.addBatch();
st.setInt(1, 2); //设置id列
st.setString(2, "LRR"); //设置name列
st.addBatch();
st.executeBatch();
st.clearBatch();
}finally{
JdbcUtils.release(conn, st, rs);
}
}
查看数据库执行情况:

可以看到使用PreparedStatement对象只能对同一条SQL语句中的占位符替代不同参数的批处理操作。
正是基于这样的设计,使我们可以利用循环,对一些具有循环性质的替代占位符的参数使用PreparedStatement对象进行批处理,还是上面的例2 ,先清空batchtest表,其他不变,就改变程序为:
public void preparedStatementBatch() throws SQLException {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
String sql = "insert into batchtest(id,name) values(?,?)";
st = conn.prepareStatement(sql);
for(int i=1;i<=5;i++) {
st.setInt(1, i); //设置id列
st.setString(2, "a"+i); //设置name列
st.addBatch();
}
st.executeBatch();
st.clearBatch();
}finally{
JdbcUtils.release(conn, st, rs);
}
}
查看数据库执行情况:

对于每次循环,都将在调用addBatch方法后将占位符已经被替代为参数的SQL语句存入PreparedStatement对象中的集合里,在下一次循环就可以进行新的占位符替代并再次存入新的SQL语句,存入SQL语句的次数和循环次数相关,因此如果循环次数过大,那么按上面的例子也将会导致程序内存溢出,解决方法就是将循环次数再分成小的循环批次一批一批地执行。

解决:

基本到此就将使用JDBC操作数据库进行批处理介绍完毕,通常我们会使用PreparedStatement对象的方式多一些,同时最后再说明一点,以上的案例我们都是使用的是MySQL数据库,对于大数据量的批处理操作,MySQL数据库的执行相比Oracle数据库的速度来说还差的很多,因此如果要对数据库执行大量的批处理操作,建议使用Oracle数据库。
使用JDBC对数据库实现批处理操作的更多相关文章
- 使用JDBC进行数据库的事务操作(1)
本篇讲述数据库中非常重要的事务概念和如何使用MySQL命令行窗口来进行数据库的事务操作.下一篇会讲述如何使用JDBC进行数据库的事务操作. 事务是指数据库中的一组逻辑操作,这个操作的特点就是在该组逻辑 ...
- 使用JDBC进行数据库的事务操作(2)
本篇将讲诉如何使用JDBC进行数据库有关事务的操作.在上一篇博客中已经介绍了事务的概念,和在MySQL命令行窗口进行开启事务,提交事务以及回滚事务的操作. 似乎事务和批处理都可以一次同时执行多条SQL ...
- JDBC自动提交和批处理操作
今天用JDBC与数据库进行交互的时候,报错如下: *************************************************************************** ...
- JDBC对数据库的简单操作
/** * 获取数据库连接 */ public Connection GetConnection(){ Connection connection=null; try { Class.forName( ...
- 使用spring框架的JdbcTemplate实现对Oracle数据库的简单操作实例
最近实现了一个小功能,针对Oracle数据库两张关联表进行查询和修改,因为比较简单,所以选择了spring框架里的JdbcTemplate.JdbcTemplate算是老古董了,是当年spring为了 ...
- JDBC操作数据库之批处理
JDBC开发中,操作数据库需要和数据库建立连接,然后将要执行的SQL语句发送到数据库服务器,最后关闭数据库连接,都是按照这样的操做的,如果按照此流程要执行多条SQL语句,那么就要建立多个数据库连接,将 ...
- JDBC操作数据库的批处理
在JDBC开发中,操作数据库需要与数据库建立连接,然后将要执行的SQL语句传送到数据库服务器,最后关闭数据库连接,都是按照这样一个流程进行操作的.如果按照该流程执行多条SQL语句,那么就需要建立多个数 ...
- 四.使用JDBC进行批处理操作
1 create table testbatch 2 ( 3 id int primary key, 4 name varchar(20) 5 ); 在实际的项目开发中,有时候需要向数据库发送一批SQ ...
- 批处理操作mysql数据库
批处理操作mysql数据库 1.使用批处理自动登录mysql数据库 @echo offcd C:\program files\mysql\mysql server 5.5\binmysql -u ro ...
随机推荐
- BZOJ 1412: [ZJOI2009]狼和羊的故事( 最小割 )
显然是最小割...把狼的领地连S, 羊的领地连T, 然后中间再连边, 跑最大流就OK了 -------------------------------------------------------- ...
- hdu1284经典钱币兑换问题
钱币兑换问题. 题目 http://acm.hdu.edu.cn/showproblem.php?pid=1284 完全背包. 这种是求背包问题最多的组合方案 参考了一些资料 http://blo ...
- MySQL 出现 The table is full 的解决方法
原文链接: MySQL 出现 The table is full 的解决方法 浅谈MySql的存储引擎(表类型) MySQL 出现 The table is full 只有一个原因,对应的表数据容量达 ...
- python成长之路——第三天
一.collections系列: collections其实是python的标准库,也就是python的一个内置模块,因此使用之前导入一下collections模块即可,collections在pyt ...
- 鹅厂揭秘——高端大气的App电量測试
怎样评价我们开发出来的应用是耗电还是不耗电,怎样測试?这就是我们今天讨论的主题--电量測试,一个在移动应用中新出现的測试类型. 作者简单介绍 watermark/2/text/aHR0cDovL2Js ...
- 数据挖掘算法学习(三)NaiveBayes算法
算法简单介绍 NBC是应用最广的分类算法之中的一个.朴素贝叶斯模型发源于古典数学理论,有着坚实的数学基础,以及稳定的分类效率.同一时候,NBC模型所需预计的參数非常少,对缺失数据不太敏感,算法也比較简 ...
- 理光C5502A 打印模糊问题
1.这款打印机好几W,我来的时候就有了.挺高端的. 2.来的时候由于网络没建成.建成之后,全部设置成网络打印机. 3.可以扫描成jpg\pdf,并且可以通过共享设置成扫描到目的地. 4.还有其它一些功 ...
- BZOJ 2510: 弱题( 矩阵快速幂 )
每进行一次, 编号为x的数对x, 和(x+1)%N都有贡献 用矩阵快速幂, O(N3logK). 注意到是循环矩阵, 可以把矩阵乘法的复杂度降到O(N2). 所以总复杂度就是O(N2logK) --- ...
- Away3D带你360°漫游全景影像
1代码展示 package { import away3d.containers.View3D; import away3d.controllers.HoverController; import a ...
- cocos2d-x游戏开发系列教程-中国象棋01-工程文件概述
上一篇博文我们看到了象棋的效果图,这一张我们来看象棋代码的整体概述 让我们先对整个代码框架有个了解. 主目录: 主目录包含内容如上图: classes目录:业务代码 proj.win32:包括main ...