一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
一、环境
数据库使用的是mysql,jdk是1.8,三种批量写入数据的方式为
- 反复执行单条插入语句
此方式简单方便,一个forEach循环搞定(本文章使用得是tkMyBatis的接口方法),如果数据量较小(20条数据左右)可使用循环insert单挑数据的方式,简单方便一个for循环就实现,但是多次与数据库进行交互,个人不建议使用。
//循环插入
@Transactional
public void add2(List<Item> itemList) {
itemList.forEach(itemMapper::insertSelective);
}
- xml拼接sql
在xml中使用标签生成sql语句,然后交由mybatis执行
<?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 namespace="com.example.insert.dao.ItemMapper">
<insert id="insertByBatch">
INSERT INTO tb_item VALUES
<foreach collection="list" item="item" index="index" separator=",">
(#{item.id},#{item.name}
</foreach>
</insert>
</mapper>
- 批处理执行
Mybatis内置的ExecutorType有3种,默认的是simple,该模式下它为每个语句的执行创建一个新的预处理语句,单条提交sql;而batch模式重复使用已经预处理的语句,并且批量执行所有更新语句,显然batch性能将更优; 但batch模式也有自己的问题,比如在Insert操作时,在事务没有提交之前,是没有办法获取到自增的id,这在某型情形下是不符合业务要求
@Service
public class ItemService {
@Autowired
private ItemMapper itemMapper;
@Autowired
private SqlSessionFactory sqlSessionFactory;
//批处理
@Transactional
public void add(List<Item> itemList) {
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH,false);
ItemMapper mapper = session.getMapper(ItemMapper.class);
for (int i = ; i < itemList.size(); i++) {
mapper.insertSelective(itemList.get(i));
if(i%1000==999){//每1000条提交一次防止内存溢出
session.commit();
session.clearCache();
}
}
session.commit();
session.clearCache();
}
//通过拼接sql方式
@Transactional
public void add1(List<Item> itemList) {
itemMapper.insertByBatch(itemList);
}
//循环插入方式
@Transactional
public void add2(List<Item> itemList) {
itemList.forEach(itemMapper::insertSelective);
}
}