PreparedStatement:
1) addBatch()将一组参数添加到PreparedStatement对象内部。
2) executeBatch()将一批参数提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
Statement:
1) addBatch(String sql)方法会在批处理缓存中加入一条sql语句。
2) executeBatch()执行批处理缓存中的所有sql语句。
注意:PreparedStatement中使用批量更新时,要先设置好参数后再使用addBatch()方法加入缓存。批量更新中只能使用更改、删除或插入语句。
package com.jdbcapi;
import java.sql.Connection;
import java.sql.Statement;
public class StatementTest {
/**
* 功能:请描述该方法具体功能<br/>
* 2014-5-8 上午11:21:26
*/
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
ConnectionFactory cf1 = ConnectionFactory.getInstance();
Connection con = cf1.getConnection();
Statement ps = con.createStatement();
try {
con.setAutoCommit(false);
ps.addBatch("insert into student values(41,'tb',null,63)");
ps.addBatch("insert into student values(42,'tbb',null,64)");
ps.addBatch("insert into student values(43,'tbbb',null,65)");
ps.executeBatch();
con.commit();
System.out.println("提交成功");
} catch (Exception e) {
e.printStackTrace();
if (!con.isClosed()) {
con.rollback();
}
}finally{
System.out.println("关闭连接");
ConnectionFactory.close(con, ps,null);
}
}
}
package com.jdbcapi;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
public class PreparedStatementTest {
/**
* 功能:请描述该方法具体功能<br/>
* 2014-5-8 上午11:21:26
*/
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
ConnectionFactory cf1 = ConnectionFactory.getInstance();
Connection con = cf1.getConnection();
PreparedStatement ps = con.prepareStatement("insert into student values(?,?,?,?)");
try {
con.setAutoCommit(false);
ps.setInt(1,18);
ps.setString(2,"test1");
ps.setDate(3,null);
ps.setFloat(4,78);
ps.addBatch();
ps.setInt(1,36);
ps.setString(2,"test2");
ps.setDate(3,null);
ps.setFloat(4,90);
ps.addBatch();
// 将一批参数提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组
ps.executeBatch();
con.commit();
System.out.println("提交成功");
} catch (Exception e) {
e.printStackTrace();
if (!con.isClosed()) {
con.rollback();
}
}finally{
ConnectionFactory.close(con, ps,null);
}
}
}
at com.mysql.jdbc.StatementImpl.executeBatch(StatementImpl.java:1007)
考虑这样一个场景,在您想要插入到数据库使用批处理上万条记录。嗯,可能产生的OutOfMemoryError:
java.lang.OutOfMemoryError: Java heap space
com.mysql.jdbc.ServerPreparedStatement$BatchedBindValues.<init>(ServerPreparedStatement.java:72)
com.mysql.jdbc.ServerPreparedStatement.addBatch(ServerPreparedStatement.java:330)
org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:171)
这是因为你试图在一个批次添加所有语句,并一次插入。最好的办法是将执行分批次。看看下面的解决方案
Smart Insert: Batch within Batch - 智能插入:将整批分批
这是一个简单的解决方案。考虑批量大小为1000,每1000个查询语句为一批插入提交。
String sql = "insert into employee (name, city, phone) values (?, ?, ?)"; Connection connection = new getConnection(); PreparedStatement ps = connection.prepareStatement(sql); final int batchSize = 1000; int count = 0; for (Employee employee: employees) { ps.setString(1, employee.getName()); ps.setString(2, employee.getCity()); ps.setString(3, employee.getPhone()); ps.addBatch(); if(++count % batchSize == 0) { ps.executeBatch(); // executeBatch() 返回后,将重新将语句的内部批处理命令列表设置为空。 } } ps.executeBatch(); // insert remaining records ps.close(); connection.close();
这才是理想的解决方案,它避免了SQL注入和内存不足的问题。看看我们如何递增计数器计数,一旦BATCHSIZE 达到 1000,我们调用executeBatch()提交。