赞
踩
最近要做一个批处理插入数据的,但是试了批处理的代码发现没有效果,很纳闷啊。但是之前在学习JDBC操作Mysql批处理的时候,记得要在数据库url中的参数加配置的,但是忘了。网速搜居然不容易搜出来,我也是醉了,难道这么重要的参数都不重视?于是就看到这一篇,感谢博主。至于这个参数就是“rewriteBatchedStatements=true”这个对批处理很大影响,没有它就相当于没有批处理。
有人说MySQL的JDBC驱动,不是真正支持批量操作的,就算你在代码中调用了批量操作的方法,MySql的JDBC驱动也是按照一般操作来处理的。
但其实并非如此,Mysql 是有特殊的方式优化整个batch insert 结果的。
可不可以先假设 batch 的方式与非batch一样,每一条insrt语句事实上均是单独发往服务器的呢?
浏览下源代码吧。
好多兄弟都描述了源代码,直接从那几个类入手吧,事实上关键的类是这个 com.mysql.jdbc.PreparedStatement
先看了其中的 addBatch 方法,没有任何问题,只是将语句添加进入一个 List 中保存。
那么 executeBatch 呢?
再贴一下吧, 关键看其中的这部分,顺带说一下, 这个mysql-jdbcdriver的源代码是 5.1.13的
MySql JDBC 驱动版本 | 结果 |
5.0.8 | 没有提高 18秒 |
5.1.7 | 没有提高 18秒 |
5.1.13 | 有提高 1.6秒 |
所以Mysql的批量操作一定要加上MySql连接的url中要加rewriteBatchedStatements参数设为true。
最后贴下代码:
- public static void batchSave() {
- new Thread() {
- public void run() {
- long start = System.currentTimeMillis();
- Connection conn = null;
- PreparedStatement pstmt = null;
- try {
- String sql = "insert into bluetooth_code_raw(rawCode, md5Code) values(?,?)";
- conn = db1.conn;
- // JAVA默认为TRUE,我们自己处理需要设置为FALSE,并且修改为手动提交,才可以调用rollback()函数
- conn.setAutoCommit(false);
- pstmt = conn.prepareStatement(sql);
- for (int i = 0; i < 100000; i++) {
- String gunCode = MagicCodeUtil.generateGunCode(0, i);
-
- pstmt.setString(1, gunCode);
- pstmt.setString(2, MagicCodeUtil.getMd5(gunCode));
- pstmt.addBatch();
- //防止内存溢出,我也不是很清楚都这么写
- if ((i + 1) % 1000 == 0) {
- pstmt.executeBatch();
- pstmt.clearBatch();
- }
- }
- pstmt.executeBatch(); // 批量执行
- conn.commit();// 提交事务
- } catch (SQLException e) {
- try {
- conn.rollback(); // 进行事务回滚
- } catch (SQLException ex) {
- e.printStackTrace();
- }
- } finally {
- if (pstmt != null)
- try {
- pstmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- if (conn != null)
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- System.out.println((System.currentTimeMillis() - start) / 1000);
- };
- }.start();
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。