JDBC基础学习(五)—批处理插入数据
一、批处理介绍
当需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率。
JDBC的批量处理语句包括下面两个方法:
addBatch(String): 添加需要批量处理的SQL语句或是参数。
executeBatct(): 执行批量处理语句。
二、批处理的使用
1.使用事务没有批处理
@Test public void testBatch(){ Connection con = null; PreparedStatement ps = null; try{ // 保证连接是唯一的,传入相同的Connnection con = JdbcTools.getConnection(); //开启事务 JdbcTools.beginTx(con); String sql = "insert into person(name,city) values(?,?)"; ps = con.prepareStatement(sql); long begin = System.currentTimeMillis(); // 插入10000条数据 for(int i = 0;i < 100000;i++){ ps.setString(1,"A"+ i); ps.setString(2,"BJ"); ps.executeUpdate(); } //提交事务 JdbcTools.commitTx(con); long end = System.currentTimeMillis(); System.out.println("Time: " + (end - begin)); //14684 }catch(Exception e){ e.printStackTrace(); // 回滚事务 JdbcTools.rollBackTx(con); }finally{ JdbcTools.releaseResource(con,null,null); } }结果: Time: 15127
2.使用事务+批处理
@Test public void testBatch2(){ Connection con = null; PreparedStatement ps = null; try{ // 保证连接是唯一的,传入相同的Connnection con = JdbcTools.getConnection(); //开启事务 JdbcTools.beginTx(con); String sql = "insert into person(name,city) values(?,?)"; ps = con.prepareStatement(sql); long begin = System.currentTimeMillis(); // 插入10000条数据 for(int i = 0;i < 100000;i++){ ps.setString(1,"A"+ i); ps.setString(2,"BJ"); //"积攒"SQL ps.addBatch(); if((i + 1) % 300 == 0){ ps.executeBatch(); ps.clearBatch(); } } if(100000 % 300 != 0){ ps.executeBatch(); ps.clearBatch(); } //提交事务 JdbcTools.commitTx(con); long end = System.currentTimeMillis(); System.out.println("Time: " + (end - begin)); //17010 }catch(Exception e){ e.printStackTrace(); // 回滚事务 JdbcTools.rollBackTx(con); }finally{ JdbcTools.releaseResource(con,null,null); } }结果: Time: 17201
看到这个结果,哎呦卧槽,你泥马不是坑爹么,这批处理逗我玩呢。经过百度、Google才得知如下的内容。
在MySQL JDBC连接字符串中还可以加入参数。
rewriteBatchedStatements=true。
mysql默认关闭了batch处理,通过此参数进行打开,这个参数可以重写向数据库提交的SQL语句。
useServerPrepStmts=false。
如果不开启(useServerPrepStmts=false),使用com.mysql.jdbc.PreparedStatement进行本地SQL拼装,最后送到db上就是已经替换了?后的最终SQL。在此稍加改进,连接字符串中加入下面语句。
connectStr += "?useServerPrepStmts=false&rewriteBatchedStatements=true";
再次运行结果: Time: 1933
越努力,越幸运!