当需要批量插入数据到数据库时,我们可以利用基础的Statement或PreparedStatement外加for循环来实现操作,但这种方式效率奇低。
因此,当需要成批插入或者更新记录时,我们可以利用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理,通常情况下比单独提交处理更有效率。
JDBC的批量处理语句包括下面三个方法:
-
addBatch(String):添加需要批量处理的SQL语句或是参数;
-
executeBatch():执行批量处理语句;
-
clearBatch():清空缓存的数据
同时,我们可以通过禁用SQL的AutoCommite功能进一步提高效率。
import JDBC.Utils;
import java.sql.*;
/*
使用preparedStatement实现更高效的批量插入
*/
public class 批量插入 {
/*
高效批量插入:
1.addBatch()、executeBatch()、clearBatch()
2.mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。
?rewriteBatchedStatements=true 写在配置文件的url后面
*/
public static void main(String[] args) {
testInsert2();
}
public static void testInsert() { //565毫秒
Connection conn = null;
PreparedStatement ps = null;
try {
conn = Utils.getConnection();
String sql = "insert into goods(name)values(?)";
ps = conn.prepareStatement(sql);
for(int i = 1;i <= 20000;i++){
ps.setObject(1, "name_" + i);
//1."攒"sql
ps.addBatch();
if(i % 500 == 0){
//2.执行batch
ps.executeBatch();
//3.清空batch
ps.clearBatch();
}
}
ps.executeBatch(); // 防止未执行完
} catch (Exception e) {
e.printStackTrace();
}finally{
Utils.closeResource(conn, ps);
}
}
//Final:设置连接不允许自动提交数据
public static void testInsert2() { // 100毫秒
Connection conn = null;
PreparedStatement ps = null;
try {
conn = Utils.getConnection();
//设置不允许自动提交数据
conn.setAutoCommit(false);
String sql = "insert into goods(name)values(?)";
ps = conn.prepareStatement(sql);
for(int i = 1;i <= 20000;i++){
ps.setObject(1, "name_" + i);
//1."攒"sql
ps.addBatch();
if(i % 500 == 0){
//2.执行batch
ps.executeBatch();
//3.清空batch
ps.clearBatch();
}
}
//提交数据
conn.commit();
} catch (Exception e) {
e.printStackTrace();
}finally{
Utils.closeResource(conn, ps);
}
}
}