mybatis批量insert到Oracle数据库

(1)使用mybatis的foreach语法:

private static void listinsert() {
		EjsonDecoder el = new EjsonDecoder().unbare();
		List<Map> list=new ArrayList<Map>();
		SqlSession session=SqlSessionUtil.sf.openSession();
		long start=System.currentTimeMillis();
		for(int logid=1;logid<=60000;logid++){
			String msg="{appCode:nihao,apptx:zzc2017021401,bizkey:CS-007,channelId:18b0kw8,city:510,methodCode:crck,province:51,reqTs:1492152950566,txid:"+ ("123456789"+logid) + "}";
			
			Map log=el.decode(msg);
			list.add(log);
			if(logid%10==0){
				session.insert("dao.DemoDao.insertAopTradeForReq",list);
				session.commit();
				session.clearCache();
				session.close();
				session=SqlSessionUtil.sf.openSession();
				list=new ArrayList<Map>();
			}
		}
		System.out.println("60万条耗时 :"+(System.currentTimeMillis()-start));
	}

对应的 SQL语句:

<insert id="insertAopTradeForReq" >
          insert into AOP_TRADE (
               LOG_ID,
               APPCODE,
               BIZKEY ,
               METHODCODE,
               APPTX,
               PROVINCE,
               CITY,
               CHANNEL_ID,
               REQTIMES,
               UPDATE_TIME
                  ) 
      <foreach collection="list" item="item" index="index" separator="union all" > 
         (select  
               #{item.txid,jdbcType=VARCHAR},
               #{item.appCode,jdbcType=VARCHAR},
               #{item.bizkey,jdbcType=VARCHAR},
               #{item.methodCode,jdbcType=VARCHAR},
               #{item.apptx,jdbcType=VARCHAR},
               #{item.province,jdbcType=VARCHAR},
               #{item.city,jdbcType=VARCHAR},
               #{item.channelId,jdbcType=VARCHAR},
              #{item.reqTs,jdbcType=NUMERIC},
               sysdate
        from dual)
    </foreach>
 </insert> 

这时:批量在list中存入10条,100条,1000条耗时分别是 54917毫秒,27949毫秒,25446毫秒。


(2)使用事务批量提交:

private static void onebyone() {
		EjsonDecoder el = new EjsonDecoder().unbare();
		//List<Map> list=new ArrayList<Map>();
		SqlSession session=SqlSessionUtil.sf.openSession(ExecutorType.BATCH,false);
		long start=System.currentTimeMillis();
		for(int logid=1;logid<=60000;logid++){
			String msg="{appCode:nihao,apptx:zzc2017021401,bizkey:CS-007,channelId:18b0kw8,city:510,methodCode:crck,province:51,reqTs:1492152950566,txid:"+ ("123456789"+logid) + "}";
			
//			if(logid==1199)
//				msg="{appCode:nihaonihaonihaonihaonihao,apptx:zzc2017021401,bizkey:CS-007,channelId:18b0kw8,city:510,methodCode:crck,province:51,reqTs:1492152950566,txid:"+ ("123456789"+logid) + "}";
//			if(logid==7199)
//				msg="{appCode:nihaonihaonihaonihaonihao,apptx:zzc2017021401,bizkey:CS-007,channelId:18b0kw8,city:510,methodCode:crck,province:51,reqTs:1492152950566,txid:"+ ("123456789"+logid) + "}";
			Map log=el.decode(msg);
			session.insert("dao.DemoDao.insertAopTradeTest", log);
			//list.add(log);
			if(logid%5000==0){
				session.commit();
				session.clearCache();
				session.close();
				session=SqlSessionUtil.sf.openSession(ExecutorType.BATCH,false);
				//list=new ArrayList<Map>();
			}
		}
		System.out.println("60万条耗时 :"+(System.currentTimeMillis()-start));
	}
这时采用5000条,10000条,20000条,30000条插入提交一次,分别耗时5798毫秒,4526毫秒,4976毫秒,4707毫秒。

(3)采用上面两者结合:

private static void combine() {
		EjsonDecoder el = new EjsonDecoder().unbare();
		List<Map> list=new ArrayList<Map>();
		SqlSession session=SqlSessionUtil.sf.openSession(ExecutorType.BATCH,false);
		long start=System.currentTimeMillis();
		for(int logid=1;logid<=60000;logid++){
			String msg="{appCode:nihao,apptx:zzc2017021401,bizkey:CS-007,channelId:18b0kw8,city:510,methodCode:crck,province:51,reqTs:1492152950566,txid:"+ ("123456789"+logid) + "}";
			
			Map log=el.decode(msg);
			list.add(log);
			if(logid%100==0){
				session.insert("dao.DemoDao.insertAopTradeForReq",list);
				if(logid%5000==0){
					session.commit();
					session.clearCache();
					session.close();
					session=SqlSessionUtil.sf.openSession(ExecutorType.BATCH,false);
				}
				list=new ArrayList<Map>();
			}
		}
		System.out.println("60万条耗时 :"+(System.currentTimeMillis()-start));
	}
实验结果为:

list存10条,100次insert提交一次:9107毫秒

list存10条,1000次insert提交一次:9034毫秒

list存100条,50次insert提交一次:8776毫秒


综上所述: 采用第二种大的方案较好。


但是涉及到批量数据提交,都要保证这些数据中没有错误数据,都可以插入到数据库中,否则根据事务原理,全都成功,或全部都不成功。这样对于安全性不高的数据差如有很高的风险,这里采用增加错误日志表的方法:

1,创建对应的错误日志表(sql语句):

BEGIN                         -- 为 aop_business 创建一个 名字为
  DBMS_ERRLOG.CREATE_ERROR_LOG('aop_trade', 'aop_trade_ERROR_LOG');
END;

2,在执行sql时加上:

insert into aop_trade values( a1,a2,a3,a4)   LOG ERRORS INTO AOP_TRADE_ERROR_LOG  REJECT LIMIT UNLIMITED

后面的多出来的便可以解决事务中有错误数据的情况。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值