easypoi使用excel模板导入10万条数据到数据库
批量导入10万+条数据到数据库解决方案
·
觉得不错的,麻烦点个免费的赞
觉得不错的,麻烦点个免费的赞
觉得不错的,麻烦点个免费的赞
需求
在一个和平的某天,客户提了一个需求,想导入10个年份的历史数据,
10个年份的历史数据,提供了一个Excel文件大小为10M,
里面数据1万6千条,关联的主子表有10个,所以本次一次性需要导入10多万条数据;
总结
开发中常见的mybatis插入有3种类型:①普通插入、②foreach遍历参数式、③ExecutorType.BATCH插入
一般导入数据不会用第一种,一般是导入插入10条以下的短数据,例如简单列少的基础数据插入;
实际开发选择用foreach,还是.BATCH,一般要看本次导入数据有多少条,及导入的表有多少列,
【条数*表列数】<【 2千】选择用foreach;超过2千数据选择.BATCH 或者 分批次foreach处理;
个人10万数据实践中,.BATCH速度最快,通用,建议使用;
5千到1万时,可以使用分批次foreach处理;
①普通插入
INSERT INTO XX_PROJECT (ID,NAME,CODE) VALUES ( #{ID},#{NAME},#{CODE} )
②foreach遍历参数式
INSERT INTO XX_PROJECT (ID,NAME,CODE) VALUES
<foreach collection="list" item="item" index="index" separator="," >
( #{item.ID},#{item.NAME},#{item.CODE} )
</foreach>
③ExecutorType.BATCH插入后续介绍具体使用方法
处理逻辑
①原本的思路是,先使用foreach一次性插入1万+数据到数据库,发生内存溢出了
②后面,我对从Excel读取过来的数据进行分割,每次拆500条数据,
再使用mybatis的foreach标签去批量插入,执行成功了,速度也还行,
但是数据再多点的时候,速度也不是很快,该慢的还是慢,
我也尝试过调大分批次的总量为800条,但是速度也不是很明显;
后续看资料发现,foreach采用的占位符替换数据的思路,在占位符过多的时候,
解析的时间会边长,插入数据过1万的时候,不建议采用;
③最后是尝试了,mybatis的ExecutorType.BATCH,速度明显变快,
10几万条数据成功插入到数据库,只要了20多秒;
最终解决代码
// XXProjectDao.java dao层方法
void insertProject(Map<String,Object> map);
// XXProjectDao.java对应的XXProjectDaoMapper语句
<insert id="insertProject" parameterType="java.util.Map">
INSERT INTO XX_PROJECT (ID,NAME,CODE) VALUES
( #{ID},#{NAME},#{CODE} )
</insert>
// service业务层具体实现
SqlSession sqlSession=null;
try{
long c1 = System.currentTimeMillis();
sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
XXProjectDao mapper = sqlSession.getMapper(XXProjectDao.class);
int batchSize = 5000;//每次到5000提交一次
for (int i = 0; i < projectList.size(); i++) {
mapper.insertProject(projectList.get(i));
if((i!=0 && i%batchSize==0) || i==projectList.size()-1){
sqlSession.commit();
//防止内存不够,清理一下
sqlSession.clearCache();
}
}
//预防漏数据,最后再提交一次
sqlSession.clearCache();
sqlSession.commit();
long c2 = System.currentTimeMillis();
logger.info("处理excel花了:"+(end-start)/1000+"秒");
logger.info("本次执行过程共"+count+"条数据,花了"+(c2-c1)/1000+"秒");
logger.info("本次导入共,花了"+(c2-start)/1000+"秒,精准时间"+(c2-start)+"毫秒");
}catch (Exception e){
e.printStackTrace();
//手动回滚异常
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
sqlSession.rollback();
}finally {
sqlSession.close();
}
更多推荐




所有评论(0)