
使用Mybatis框架批量插入的3种方法:多次调用insert方法、foreach标签、batch模式,下面分别详解@mikechen
多次调用insert插入
这种方式理解起来最简单,一个单独的插入接口,业务上循环调用即可。
1.增加Mapper接口
@Mapper
public interface InsertMapper {
/**
* 写入
* @param po
* @return
*/
int save(@Param("po") MoneyPo po);
}
2.对应XML配置
<resultMap id="BaseResultMap" type="com.mikechen.mybatis.entity.UserPo">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="money" property="money" jdbcType="INTEGER"/>
<result column="is_deleted" property="isDeleted" jdbcType="TINYINT"/>
<result column="create_at" property="createAt" jdbcType="TIMESTAMP"/>
<result column="update_at" property="updateAt" jdbcType="TIMESTAMP"/>
</resultMap>
<insert id="save" parameterType="com.mikechen.mybatis.entity.MoneyPo" useGeneratedKeys="true" keyProperty="po.id">
INSERT INTO `user` (`name`, `money`, `is_deleted`)
VALUES
(#{po.name}, #{po.money}, #{po.isDeleted});
</insert>
3.业务逻辑代码
private UserPo buildPo() {
UserPO po = new UserPo();
po.setName("mikechen");
po.setMoney((long) random.nextInt(12343));
po.setIsDeleted(0);
return po;
}
public void testBatchInsert() {
for (int i = 0; i < 10; i++) {
moneyInsertMapper.save(buildPo());
}
}
这种方式的优点就是简单直观,缺点就是db交互次数多,开销大。
foreach插入
这种方法是依靠 MyBatis 中的 foreach 标签,将数据拼接成一条原生的 insert 语句一次性执行的。
1.增加插入接口
@Mapper
public interface UserMapper extends BaseMapper<User> {
boolean saveBatchByNative(List<User> list);
}
2.创建UserMapper.xml 文件
使用 foreach 标签拼接 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 namespace="com.example.demo.mapper.UserMapper">
<insert id="saveBatchByNative">
INSERT INTO `USER`(`NAME`,`PASSWORD`) VALUES
<foreach collection="list" separator="," item="item">
(#{item.name},#{item.password})
</foreach>
</insert>
</mapper>
3.业务逻辑实现
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService {
@Autowired
private UserMapper userMapper;
public boolean saveBatchByNative(List<User> list) {
return userMapper.saveBatchByNative(list);
}
}
使用sql批量插入的方式,优点是db交互次数少,在插入数量可控时,相比于前者开销更小。
缺点也很明显,当一次插入的数量太多时,组装的sql既有可能直接超过了db的限制无法执行了。
batch模式插入
针对上面做一个简单的优化,使用BATCH批处理模式,实现会话复用,避免每次请求都重新维护一个链接导致额外开销。
使用如下:
@Autowired
private SqlSessionFactory sqlSessionFactory;
//通过Mybatis batch模式批量插入群组人员
//开启BATCH批量模式
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
TIdReGroupUserMapper tIdReGroupUserMapper = sqlSession.getMapper(TIdReGroupUserMapper.class);
int addNum = 0;
try {
TIdReGroupUser tIdReGroupUser = new TIdReGroupUser();
for (int i = 0; i < userIds.length; i++) {
tIdReGroupUser.setId(UUID.randomUUID().toString());
tIdReGroupUser.setGroupId(groupId);
tIdReGroupUser.setUserId(userIds[i]);
addNum += tIdReGroupUserMapper.insert(tIdReGroupUser);
}
sqlSession.commit();
}finally {
closeSqlSession(sqlSession, sqlSessionFactory);
}
}
使用Mybatis的batch模式进行批量插入,数据量较大的场景中后者效率更高。
mikechen睿哥
10年+一线大厂架构实战专家,就职于阿里、淘宝等一线大厂,操盘多个亿级大厂核心项目。