我这里的需求是通过自己的逻辑将得到的所有数据(万级以上)依次插入到指定的表中,在这种在同一事务范围的情况下,我采取的是分批次(insertBatch)插入,主要思路是先将需要插入的数据依次放到一个list集合中,然后调用MyBatis下SqlSession.openSession(ExecutorType execType, boolean autoCommit)方法来实现批量处理和手动提交,第一的参数ExecutorType处理器类型有三种,分别是:
- ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情。它为每个语句的执行创建一个新的预处理语句。
- ExecutorType.REUSE: 这个执行器类型会复用预处理语句。
- ExecutorType.BATCH:这个执行器会批量执行所有更新语句,如果 SELECT 在它们中间执行还会标定它们是 必须的,来保证一个简单并易于理解的行为。 第二个参数autoCommit,true或者不写表示自动提交,false表示手动提交,调用如下:
DefaultSqlSessionFactory sqlSessionFactoryBean = SpringUtils.getBean("sqlSessionFactory");
SqlSession batchSqlSession = sqlSessionFactoryBean.openSession(ExecutorType.BATCH,false);
我所使用的主要源码是:
public static void insertDbDataBaseCheck(List<DbDatabaseCheck> dbList){
SqlSession batchSqlSession = null;
try {
DefaultSqlSessionFactory sqlSessionFactoryBean = SpringUtils.getBean("sqlSessionFactory");
batchSqlSession = sqlSessionFactoryBean.openSession(ExecutorType.BATCH,false);
int batchCount = 100;// 每批commit的个数
int batchLastIndex = batchCount;// 每批最后一个的下标
if(dbList.size() > 100) {
for (int index = 0; index < dbList.size();) {
if(batchLastIndex > dbList.size()){
Static.dbDatabaseCheckDao.insertBatch(dbList.subList(index, batchLastIndex));
batchSqlSession.commit();
System.out.println("index:" + index+ " batchLastIndex:" + batchLastIndex);
break;// 数据插入完毕,退出循环
}else {
Static.dbDatabaseCheckDao.insertBatch(dbList.subList(index, batchLastIndex));
batchSqlSession.commit();
System.out.println("index:" + index+ " batchLastIndex:" + batchLastIndex);
index = batchLastIndex;// 设置下一批下标
batchLastIndex = index + (batchCount - 1);
}
}
batchSqlSession.commit();
}else {
Static.dbDatabaseCheckDao.insertBatch(dbList);
batchSqlSession.commit();
}
} catch (Exception e) {
// TODO: handle exception
}finally {
batchSqlSession.close();
}
}