我们在项目中会有一些批量操作的场景,比如导入文件批量处理数据的情况(批量新增商户、批量修
改商户信息),当数据量非常大,比如超过几万条的时候,在Java代码中循环发送SQL到数据库执行肯
定是不现实的,因为这个意味着要跟数据库创建几万次会话。
即使在同一个连接中,也有重复编译和执行SQL的开销。
批量插入
一般思路:使用for循环,循环调用insert语句进行插入操作。
@Test
void testBatchInsert() throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
long startCurrentTime = System.currentTimeMillis();
System.out.println("start:"+startCurrentTime);
SqlSession sqlSession = sqlSessionFactory.openSession();
DeviceMapper deviceMapper = sqlSession.getMapper(DeviceMapper.class);
for (int i=1;i<=30000;i++){
//创建Session
deviceMapper.insert(Device.builder().id(i).build());
//每次操作提交
sqlSession.commit();
}
sqlSession.close();
long endCurrentTime = System.currentTimeMillis();
System.out.println("end:"+endCurrentTime);
System.out.println("总耗时:"+ (endCurrentTime-startCurrentTime) +"ms");
System.out.println("总耗时:"+(endCurrentTime-startCurrentTime)/1000+"s");
}
执行结果:
start:1675532044001
end:1675532082837
总耗时:38836ms
总耗时:38s
这是的xml配置是这样的:
<insert id="insert">
insert into t_device (id, sn) values (
#{id}, #{sn}
)
</insert>
它相当于是循环调用insert语句,每次插入一条,每次提交。
而批量插入的SQL语法,是在values后面增加插入的值,如下:
<insert id="batchInsert" parameterType="java.util.List">
insert into t_device (id,sn) values
<foreach collection="list" item="device" separator=",">
(#{device.id},#{device.sn})
</foreach>
</insert>
测试代码如下:
@Test
void testBatchInsertBatch() throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession();
DeviceMapper deviceMapper = sqlSession.getMapper(