当需要成批插入或者更新记录时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
JDBC的批量处理语句包括下面三个方法:
通常我们会遇到两种批量执行SQL语句的情况:
举例:向数据表中插入20000条数据
CREATE TABLE goods(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
Connection conn = JDBCUtils.getConnection();
Statement st = conn.createStatement();
for(int i = 1;i <= 20000;i++){
String sql = "insert into goods(name) values('name_' + "+ i +")";
st.executeUpdate(sql);
}
long start = System.currentTimeMillis();
Connection conn = JDBCUtils.getConnection();
String sql = "insert into goods(name)values(?)";
PreparedStatement ps = conn.prepareStatement(sql);
for(int i = 1;i <= 20000;i++){
ps.setString(1, "name_" + i);
ps.executeUpdate();
}
long end = System.currentTimeMillis();
System.out.println("花费的时间为:" + (end - start));//82340
JDBCUtils.closeResource(conn, ps);
/**
* ClassName: InsertTest
* Description:
* 使用PreparedStatement实现批量数据操作
* update、delete 本身就具有批量操作的效果
* 此时批量操作,主要是指的批量插入 使用PreparedStatement如何实现高效的批量插入?
*
* @Create 2023/10/30 18:36
* @Version 1.0
*/
public class InsertTest {
// 批量插入方式二:使用PreparedStatement
@Test
public void testInsert() {
Connection conn = null;
PreparedStatement ps = null;
try {
long start = System.currentTimeMillis();
conn = JDBCUtil.getConnection();
String sql = "insert into goods(name) values (?)";
ps = conn.prepareStatement(sql);
for (int i = 0; i < 2000; i++) {
ps.setObject(1, "name_" + i);
ps.execute();
}
long end = System.currentTimeMillis();
System.out.println("花费的时间 = " + (end - start));
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JDBCUtil.closeResource(conn, ps);
}
}
/**
* 批量插入方式三:使用PreparedStatement (最终版)
* 1 addBatch() executeBatch clearBatch()
* 2 mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理
* rewriteBatchedStatements=true
*/
@Test
public void testInsert2() {
Connection conn = null;
PreparedStatement ps = null;
try {
long start = System.currentTimeMillis();
conn = JDBCUtil.getConnection();
String sql = "insert into goods(name) values (?)";
ps = conn.prepareStatement(sql);
for (int i = 1; i <= 2000; i++) {
ps.setObject(1, "name_" + i);
// 1 攒 sql
ps.addBatch();
if (i % 500==0){
// 2 执行batch
ps.executeBatch();
// 3 清空batch
ps.clearBatch();
}
}
long end = System.currentTimeMillis();
System.out.println("花费的时间 = " + (end - start));
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JDBCUtil.closeResource(conn, ps);
}
}
/**
* 批量插入方式四:设置链接不允许自动提交
* 1 addBatch() executeBatch clearBatch()
* 2 mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理
* rewriteBatchedStatements=true
*/
@Test
public void testInsert3() {
Connection conn = null;
PreparedStatement ps = null;
try {
long start = System.currentTimeMillis();
conn = JDBCUtil.getConnection();
// 设置不允许提交
conn.setAutoCommit(false);
String sql = "insert into goods(name) values (?)";
ps = conn.prepareStatement(sql);
for (int i = 1; i <= 2000; i++) {
ps.setObject(1, "name_" + i);
// 1 攒 sql
ps.addBatch();
if (i % 500==0){
// 2 执行batch
ps.executeBatch();
// 3 清空batch
ps.clearBatch();
}
}
// 提交数据
conn.commit();
long end = System.currentTimeMillis();
System.out.println("花费的时间 = " + (end - start));
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JDBCUtil.closeResource(conn, ps);
}
}
}