(2)JDBC (C3P0)大批量数据的插入、更新实用方法。(实战篇)-个人总结

 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已     的形式保存起来, 下次再来执行,不需要编译直接找对应的V ,就是从缓存中找到已被编译过的语句然后直接就执行了。当然也得说一下硬解码,妈的其实硬解码就是发一次 就--语法检查--什么什么的--权限检查--编译)明白了吧?哇哈哈~而prepareStatement 恰恰就是软解码的 所以快。所以在执行多条Sql的时候就用prepareStatement,但如果就执行一次Sql的话就用statement 。还有就是第一次用prepareStatement有点慢,要添加到缓存中的嘛(大家第一次都是这样的 以后就好了)。
(3).肯定有人在纠结一个问题...就是用不用List?
        应该这样说:是查一点插一点快呢?还是全查出来放List里面再插到数据库中快呢? 其实这和数据库的缓存设置也有点关系的,当然俩个方法我都实验过,但有一个小问题啊,就是数据量太大 你放到list中会报内存溢出(list网上说可以放8G 内存定的,俺没试过哦~这叫俺咋试),有人说放一点清一点 ,那这还不   是分段嘛 ,   上面我也说了上面的 pstmt1 和list在这实现的效果一样。所以最后用了上述方法。
        我这边比较复杂的SQL一般50W条300多秒这样。希望给你得到帮助~


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



你可能感兴趣的:(JDBC_大类)