(2)JDBC (C3P0)大批量数据的插入、更新实用方法。(实战篇)-个人总结
来源:互联网 发布:windows虚拟机 mac os 编辑:程序博客网 时间:2024/06/01 15:10
1.简单,实用,高效的 分段Batch 提交方法
其实C3P0你直接可以理解为JDBC,只是封装了一下下而已,但封装了一下下就好用多了哦,首先说一下 我这边的数据量实在千万级的,提高效率的方法有很多的,当然这边写的方法 是我认为 在再用JAVA简单控制不同数据库的情况下能控制效率的最好办法了(下面的代码都是我经过实践出来的,我基本上把网上所有的方法都跑了一遍 目前觉得这样写法效率最高,请注意看注释!!!!)首先贴上一段写法代码如下:
//参数集 static int COUNT = 0; // 负责统计提交数 static Connection conn = null; static Connection conn1 = null; static ResultSet rs = null; static PreparedStatement pstmt = null; static PreparedStatement pstmt1 = null; static PreparedStatement mySelect = null; static int ALLCOUNT = 0; static int SELECTCIUNT = 0; // 查询条数 public static void INSERT_EMP()throws Exception { conn = DBManager.getConnection();//从库 conn1 = DBManager.getConnection1();//主库 conn1.setAutoCommit(false);//设置手动提交 try {pstmt = conn.prepareStatement("SELECT *FROM EMP");//假如有1000W数据 rs = pstmt.executeQuery(); //查询数据,执行了这句才是进数据库查 pstmt1= conn1.prepareStatement("INSERT INTO EMP VALUES(?,?,?,?,?)"); int insertCount=0;//插入的条数while (rs.next()) {SELECTCIUNT++;pstmt1.setString(1, rs.getString(1));pstmt1.setString(2, rs.getString(2));pstmt1.setString(3, rs.getString(3));pstmt1.setString(4, rs.getString(4));pstmt1.setTimestamp(5, Update_Time);insertCount+=pstmt1.getFetchSize();//可以获得SET到pstmt1里面的参数的个数COUNT++;ALLCOUNT++;pstmt1.addBatch();//把所有查出来的数据set到pstmt1里面(你可以理解它为一个集合),但没有提交哦~只是放在pstmt1里面。if(COUNT==100000){//当循环10W次的提交一次 pstmt1.executeBatch();//这才是向数据库发送语句 conn1.commit();//提交一下下 COUNT=0;//把循环次数设为0 pstmt1= conn1.prepareStatement(Insert_MySql_V_R_I_001);//这句话不要遗漏,不然会导致只能插入1OW条。 pstmt1.clearBatch();//清除pstmt1里面所有的值。}} //这3行别忘了写 pstmt1.executeBatch(); conn1.commit(); pstmt1.clearBatch();} catch (SQLException e) { conn1.rollback();} finally{ attemptClose(rs); attemptClose(pstmt); attemptClose(pstmt1); attemptClose(conn); attemptClose(conn1);}} //下面3个是简单封装的关闭 static void attemptClose(ResultSet o) { try { if (o != null) o.close(); } catch (Exception e) { e.printStackTrace(); } } static void attemptClose(Statement o) { try { if (o != null) o.close(); } catch (Exception e) { e.printStackTrace(); } } static void attemptClose(Connection o) { try { if (o != null) o.close(); } catch (Exception e) { e.printStackTrace(); } }}
以上的代码有几点我简单说明一下
原理:很简单 select 从库 where ROWNUM=10000 INSERT INTO 主库;(两库不在同一IP段)其实看注释和代码就能明白了
简单注意点:
(1).conn.setAutoCommit(false);//设置(false)手动提交 (true) 是自动提交 不写是默认自动提交,有啥区别捏?
以寡人一百年的编程经验觉得 就是在你INSERT数据的时候,设置了(false) 那么你插100条 如果插到50条的时候出错了,那么你前面插 得 就不会插到数据库中,因为你手动控制事务的,就是我代码里面最后才commit的。当然如果是(true) 50条的出错之前插的数据就还在数据库中,这样会造成插一点,留一点 专业的称呼 叫 《 脏数据》(哎~就是没插干净偷笑)
(2).为什么用prepareStatement 而不用statement?
之间的效率我自己也测试过,大数据量的情况下确实有很大的差距,簡単说一下我对着俩鸟的理解 一般菜鸟面试的时候会被问到哦 你可以这样回答它们prepareStatement 比statement快,因为prepareStatement是预编译的,(预编译可以理解为--软解码:数据库有个缓存策略,就是把以前执行过的SQL已 <K,V>的形式保存起来, 下次再来执行,不需要编译直接找对应的V ,就是从缓存中找到已被编译过的语句然后直接就执行了。当然也得说一下硬解码,妈的其实硬解码就是发一次 就--语法检查--什么什么的--权限检查--编译)明白了吧?哇哈哈~而prepareStatement 恰恰就是软解码的 所以快。所以在执行多条Sql的时候就用prepareStatement,但如果就执行一次Sql的话就用statement 。还有就是第一次用prepareStatement有点慢,要添加到缓存中的嘛(大家第一次都是这样的 以后就好了)。
(3).肯定有人在纠结一个问题...就是用不用List?
应该这样说:是查一点插一点快呢?还是全查出来放List里面再插到数据库中快呢? 其实这和数据库的缓存设置也有点关系的,当然俩个方法我都实验过,但有一个小问题啊,就是数据量太大 你放到list中会报内存溢出(list网上说可以放8G 内存定的,俺没试过哦~这叫俺咋试),有人说放一点清一点 ,那这还不 是分段嘛 , 上面我也说了上面的 pstmt1 和list在这实现的效果一样。所以最后用了上述方法。
我这边比较复杂的SQL一般50W条300多秒这样。希望给你得到帮助~
简单注意点:
(1).conn.setAutoCommit(false);//设置(false)手动提交 (true) 是自动提交 不写是默认自动提交,有啥区别捏?
以寡人一百年的编程经验觉得 就是在你INSERT数据的时候,设置了(false) 那么你插100条 如果插到50条的时候出错了,那么你前面插 得 就不会插到数据库中,因为你手动控制事务的,就是我代码里面最后才commit的。当然如果是(true) 50条的出错之前插的数据就还在数据库中,这样会造成插一点,留一点 专业的称呼 叫 《 脏数据》(哎~就是没插干净偷笑)
(2).为什么用prepareStatement 而不用statement?
之间的效率我自己也测试过,大数据量的情况下确实有很大的差距,簡単说一下我对着俩鸟的理解 一般菜鸟面试的时候会被问到哦 你可以这样回答它们prepareStatement 比statement快,因为prepareStatement是预编译的,(预编译可以理解为--软解码:数据库有个缓存策略,就是把以前执行过的SQL已 <K,V>的形式保存起来, 下次再来执行,不需要编译直接找对应的V ,就是从缓存中找到已被编译过的语句然后直接就执行了。当然也得说一下硬解码,妈的其实硬解码就是发一次 就--语法检查--什么什么的--权限检查--编译)明白了吧?哇哈哈~而prepareStatement 恰恰就是软解码的 所以快。所以在执行多条Sql的时候就用prepareStatement,但如果就执行一次Sql的话就用statement 。还有就是第一次用prepareStatement有点慢,要添加到缓存中的嘛(大家第一次都是这样的 以后就好了)。
(3).肯定有人在纠结一个问题...就是用不用List?
应该这样说:是查一点插一点快呢?还是全查出来放List里面再插到数据库中快呢? 其实这和数据库的缓存设置也有点关系的,当然俩个方法我都实验过,但有一个小问题啊,就是数据量太大 你放到list中会报内存溢出(list网上说可以放8G 内存定的,俺没试过哦~这叫俺咋试),有人说放一点清一点 ,那这还不 是分段嘛 , 上面我也说了上面的 pstmt1 和list在这实现的效果一样。所以最后用了上述方法。
我这边比较复杂的SQL一般50W条300多秒这样。希望给你得到帮助~
注:文中出现错别字,或者脏话等莫怪~转载请注明出处
--苏州 黑无常
0 0
- (2)JDBC (C3P0)大批量数据的插入、更新实用方法。(实战篇)-个人总结
- (1)JDBC (C3P0)大批量数据的插入、更新实用方法。(配置篇)-个人总结
- 大批量数据的插入
- 大批量快速插入数据方法
- 大批量更新数据mysql批量更新的四种方法
- 大批量更新数据mysql批量更新的四种方法
- 大批量数据更新数据库中的表(DataSet)
- jdbc使用(c3p0)
- 向ACCESS大批量快速插入数据的方法
- 提高Sqlserver大批量插入数据速度的几点方法
- jdbc连接数据库的7大步骤(以通过jdbc连接实现数据的插入、更新为例)
- Hibernate大批量的数据更新缓存问题(Could not synchronize database state with session)
- 关于大批量数据上传和更新的方法
- jdbc批量插入实现大批量数据快速插入
- jquery的事件总结实用篇(持续更新)
- JDBC中DoInsert(插入数据)与DoSelect(查询数据)方法的实现
- 实用Google 搜索方法总结(持续更新)
- JDBC连接池(c3p0)
- ASCII Unicode和UTF-8
- LeetCode 之 Construct Binary Tree from Inorder and Postorder Traversal
- 计数排序
- QML--学习第二篇
- 黑马程序员_泛型详解
- (2)JDBC (C3P0)大批量数据的插入、更新实用方法。(实战篇)-个人总结
- VMware虚拟机下linux上网的几种方式
- linux虚拟机中和主机三种网络连接方式的区别
- ActionBar的下拉了列框
- ios多线程概述
- python 类详解
- 不要做多余的事,不要说多余的话
- 12月战斗还是停不下来,继续干吧!
- 对Android开发者有益的40条优化建议