批量操作
1 批量执行SQL语句
-
当需要成批插入或者更新记录时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
-
JDBC的批量处理语句包括下面三个方法:
addBatch(String)
:添加需要批量处理的SQL语句或是参数;executeBatch()
:执行批量处理语句;clearBatch()
:清空缓存的数据
-
通常我们会遇到两种批量执行SQL语句的情况:
- 多条SQL语句的批量处理;
- 一个SQL语句的批量传参;
2 实现层次一:使用Statement
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);
}
3 实现层次二:使用PreparedStatement
/*
* 基础测试:479117毫秒
*/
public static void test01() {
Connection conn = null;
try {
conn = JDBCTools.getConn();
long start = System.currentTimeMillis();
String sql = "insert into goods (name) values (?)";
PreparedStatement ps = conn.prepareStatement(sql);
for (int i = 0; i < 20000; i++) {
ps.setString(1, "name_" + i);
ps.execute();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.close(conn);
}
}
4 实现层次三:使用Batch的方式进行批量插入操作
- 使用Batch的方式进行批量插入操作:1018毫秒
- 需要在DB连接时候使用的URL后追加
?rewriteBatchedStatements=true
来打开批处理的权限,即:url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true
- 同时更新 mysql-connector-java-5.1.7-bin.jar 到 mysql-connector-java-5.1.37-bin.jar
- 需要在DB连接时候使用的URL后追加
public static void test02() {
Connection conn = null;
try {
conn = JDBCTools.getConn();
long start = System.currentTimeMillis();
String sql = "insert into goods (name) values (?)";
PreparedStatement ps = conn.prepareStatement(sql);
for (int i = 0; i < 20000; i++) {
ps.setString(1, "name_" + i);
// 将SQL语句缓存到批处理中
ps.addBatch();
if (i % 500 == 0) {
// 每500条执行一次批处理
ps.executeBatch();
// 执行结束后清空批处理中缓存的语句
ps.clearBatch();
}
}
long end = System.currentTimeMillis();
System.out.println(end - start);
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.close(conn);
}
}
5 实现层次四:更改提交方式
- 更改提交方式:296毫秒
- 针对于以上的方法,每500条插入一次,由于设置自动提交,向数据库提交500条数据,数据库就执行500条的插入
- 再次提高效率,先将自动提交关闭后,等待所有SQL均提交到数据库后统一执行
public static void test03() {
Connection conn = null;
try {
conn = JDBCTools.getConn();
// 关闭自动提交
conn.setAutoCommit(false);
long start = System.currentTimeMillis();
String sql = "insert into goods (name) values (?)";
PreparedStatement ps = conn.prepareStatement(sql);
for (int i = 0; i < 20000; i++) {
ps.setString(1, "name_" + i);
// 将SQL语句缓存到批处理中
ps.addBatch();
if (i % 500 == 0) {
// 每500条执行一次批处理
ps.executeBatch();
// 执行结束后清空批处理中缓存的语句
ps.clearBatch();
}
}
// 所有语句提交之后统一执行
conn.commit();
long end = System.currentTimeMillis();
System.out.println(end - start);
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.close(conn);
}
}