(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多秒这样。希望给你得到帮助~


                                                        注:文中出现错别字,或者脏话等莫怪~转载请注明出处
                                                                                                                                                                            
                                                                                                                                                --苏州  黑无常



0 0
原创粉丝点击