年轻人不讲武德,耗子尾汁。哈哈,来吧,新鲜出炉的数据批量导入数据库,这上周优化代码,采用批量导入数据,速度处理起来就是快很多很多,闲话少说,直接扔干货。
组长让完成csv文件导入数据库,之前的csv文件内容大概也就几千条数据,在运行的时候没有丝毫的感觉慢,但是后期一下子加到了大概三万多条,一下子让我等了大概八分钟作用,乖乖类,没办法,干吧,优化代码。之前我采用的是放到list的集合中,每读取一条数据,然后进行调用mapper语句,插入数据库,现在按照这八分钟才插入结束,肯定不行了,必须优化。
这个插入数据我由单条插入数据更改为采用批量插入数据,具体实现步骤如下图所示:
第一步:获取sqlsession,从spring中注入sqlSession
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
第二步:获取一个模式为BATCH,自动提交为false的session。PS:batch模式重复使用已经预处理的语句,并且批量执行所有更新语句
SqlSession sqlSession= sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false);
第三步:通过新获取的session获取mapper.
TestMapper mapper = sqlSession.getMapper(TestMapper.class);
第四步:开始进行批量导入数据,代码如下所示
int batchCount = 5000;//每批次导入的最大数据
int batchLastIndex = batchCount;//每批最后一条数据下标等于批量大小
//批量插入 index 为 下标
for (int index = 0; index < tests.size(); ) {
//如果csv读取的数量大小 小于 批量大小
if (tests.size() < batchLastIndex) {
batchLastIndex = tests.size();
mapper.testIntoSql(tests.subList(index, batchLastIndex));
//清楚缓存
sqlSession.clearCache();
break;
} else {
mapper.testIntoSql(tests.subList(index, batchLastIndex));
//清除缓存 防止溢出
sqlSession.clearCache();
index = batchLastIndex;
batchLastIndex = index + (batchCount - 1);
}
}
//将数据提交到数据库,否则的话只是执行,但是并没有提交数据到数据库
sqlSession.commit();
//关闭
sqlSession.close();
注意: 一定要记得最后提交事务(会将磁盘缓存中的数据写入磁盘的数据库中,我们这里设置成了关闭自动提交,因此必须手动提交),也就是commit。还有记得清除缓存,防止溢出。
好了,这些是处理数据批量导入的主要逻辑,下面给大家引入下xml文件的SQL语句:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--注意换成自己的mapper文件地址-->
<mapper namespace="com.ygl.mapper.TestMapper">
<insert id="testIntoSql" parameterType="Test" useGeneratedKeys="false">
insert into test01 (id,name,age,address) values
<foreach collection="list" item="item" index="index" separator=",">
(
#{item.id},
#{item.name},
#{item.age},
#{item.address}
)
</foreach>
</insert>
</mapper>
注意: 我这里xml文件中采用的mySql数据库,如果采用的oracle数据库,大家要记得更改下哈。