接口 io.mybatis.mapper.list.ListMapper<T>
# 批量插入
这个接口算示例,没有包含在 Mapper
中,提供下面一个方法:
int insertList(@Param("entityList") List<? extends T> entityList);
: 批量插入
需要数据库支持 INSERT TABLE(C1,C2...) VALUES(...), (....)
语法才可以。
# 批量更新
2.1.0 版本之后增加了新的方法:
/**
* 批量更新
*
* @author dengsd
* @date 2022/9/27 11:49
*/
@Lang(Caching.class)
@UpdateProvider(type = ListProvider.class, method = "updateList")
int updateList(@Param("entityList") List<? extends T> entityList);
/**
* 批量更新
*
* @author dengsd
* @date 2022/9/27 11:49
*/
@Lang(Caching.class)
@UpdateProvider(type = ListProvider.class, method = "updateListSelective")
int updateListSelective(@Param("entityList") List<? extends T> entityList);
上述方法示例(单测):
public class BatchUpdateMapperTest extends H2BaseMapperTest {
@Test
public void testUpdateList() {
SqlSession sqlSession = getSqlSession();
try {
TestBatchUpdateMapper batchUpdateUserIdsMapper = sqlSession.getMapper(TestBatchUpdateMapper.class);
List<UserIds> users = new ArrayList<>(10);
for (int i = 0; i < 2; i++) {
UserIds user = new UserIds();
user.setId1(1L);
user.setId2(i + 1L);
user.setName("测试" + i);
users.add(user);
}
Assert.assertEquals(2, batchUpdateUserIdsMapper.updateList(users));
sqlSession.rollback();
} finally {
//不要忘记关闭sqlSession
sqlSession.close();
}
}
@Test
public void testUpdateListSelective() {
SqlSession sqlSession = getSqlSession();
try {
TestBatchUpdateMapper batchUpdateUserIdsMapper = sqlSession.getMapper(TestBatchUpdateMapper.class);
List<UserIds> users = new ArrayList<>(10);
UserIds user3 = new UserIds();
user3.setId1(1L);
user3.setId2(3L);
user3.setName(null);
users.add(user3);
UserIds beforeData = batchUpdateUserIdsMapper.selectByPrimaryKey(user3).get();
for (int i = 0; i < 2; i++) {
UserIds user = new UserIds();
user.setId1(1L);
user.setId2(i + 1L);
user.setName("测试" + i);
users.add(user);
}
Assert.assertEquals(3, batchUpdateUserIdsMapper.updateListSelective(users));
UserIds afterData = batchUpdateUserIdsMapper.selectByPrimaryKey(user3).get();
Assert.assertEquals(beforeData.getName(), afterData.getName());
sqlSession.rollback();
} finally {
//不要忘记关闭sqlSession
sqlSession.close();
}
}
}
updateList
方法生成的xml代码:
<script>
UPDATE user_ids
<trim prefix="SET" suffixOverrides="," suffix=" ">
<trim prefix="id1 = CASE " suffixOverrides="" suffix="end, ">
<foreach collection="entityList" item="entity" separator=" ">
WHEN ( id1 = #{entity.id1} AND id2 = #{entity.id2}) THEN #{entity.id1}
</foreach>
</trim>
<trim prefix="id2 = CASE " suffixOverrides="" suffix="end, ">
<foreach collection="entityList" item="entity" separator=" ">
WHEN ( id1 = #{entity.id1} AND id2 = #{entity.id2}) THEN #{entity.id2}
</foreach>
</trim>
<trim prefix="name = CASE " suffixOverrides="" suffix="end, ">
<foreach collection="entityList" item="entity" separator=" ">
WHEN ( id1 = #{entity.id1} AND id2 = #{entity.id2}) THEN #{entity.name}
</foreach>
</trim>
</trim>
<where>
(id1,id2) in (
<foreach collection="entityList" item="entity" open="(" close=")" separator="),(">
#{entity.id1},#{entity.id2}
</foreach>
)
</where>
</script>
输出的日志:
17:31:55.707 [main] DEBUG i.m.m.T.updateList - ==> Preparing: UPDATE user_ids SET id1 = CASE WHEN ( id1 = ? AND id2 = ?) THEN ? WHEN ( id1 = ? AND id2 = ?) THEN ? end, id2 = CASE WHEN ( id1 = ? AND id2 = ?) THEN ? WHEN ( id1 = ? AND id2 = ?) THEN ? end, name = CASE WHEN ( id1 = ? AND id2 = ?) THEN ? WHEN ( id1 = ? AND id2 = ?) THEN ? end WHERE (id1,id2) in ( ( ?,? ),( ?,? ) )
17:31:55.786 [main] DEBUG i.m.m.T.updateList - ==> Parameters: 1(Long), 1(Long), 1(Long), 1(Long), 2(Long), 1(Long), 1(Long), 1(Long), 1(Long), 1(Long), 2(Long), 2(Long), 1(Long), 1(Long), 测试0(String), 1(Long), 2(Long), 测试1(String), 1(Long), 1(Long), 1(Long), 2(Long)
17:31:55.791 [main] DEBUG i.m.m.T.updateList - <== Updates: 2
updateListSelective
方法生成的xml代码:
<script>
UPDATE user_ids
<trim prefix="SET" suffixOverrides="," suffix=" ">
<trim prefix="id1 = CASE " suffixOverrides="" suffix="end, ">
<foreach collection="entityList" item="entity" separator=" ">
<choose>
<when test="entity.id1 != null">
WHEN ( id1 = #{entity.id1} AND id2 = #{entity.id2}) THEN #{entity.id1}
</when>
<otherwise>
WHEN ( id1 = #{entity.id1} AND id2 = #{entity.id2} ) THEN id1
</otherwise>
</choose>
</foreach>
</trim>
<trim prefix="id2 = CASE " suffixOverrides="" suffix="end, ">
<foreach collection="entityList" item="entity" separator=" ">
<choose>
<when test="entity.id2 != null">
WHEN ( id1 = #{entity.id1} AND id2 = #{entity.id2}) THEN #{entity.id2}
</when>
<otherwise>
WHEN ( id1 = #{entity.id1} AND id2 = #{entity.id2} ) THEN id2
</otherwise>
</choose>
</foreach>
</trim>
<trim prefix="name = CASE " suffixOverrides="" suffix="end, ">
<foreach collection="entityList" item="entity" separator=" ">
<choose>
<when test="entity.name != null">
WHEN ( id1 = #{entity.id1} AND id2 = #{entity.id2}) THEN #{entity.name}
</when>
<otherwise>
WHEN ( id1 = #{entity.id1} AND id2 = #{entity.id2} ) THEN name
</otherwise>
</choose>
</foreach>
</trim>
</trim>
<where>
(id1,id2) in (
<foreach collection="entityList" item="entity" open="(" close=")" separator="),(">
#{entity.id1},#{entity.id2}
</foreach> )
</where>
</script>
输出的日志:
17:31:55.928 [main] DEBUG i.m.m.T.updateListSelective - ==> Preparing: UPDATE user_ids SET id1 = CASE WHEN ( id1 = ? AND id2 = ?) THEN ? WHEN ( id1 = ? AND id2 = ?) THEN ? WHEN ( id1 = ? AND id2 = ?) THEN ? end, id2 = CASE WHEN ( id1 = ? AND id2 = ?) THEN ? WHEN ( id1 = ? AND id2 = ?) THEN ? WHEN ( id1 = ? AND id2 = ?) THEN ? end, name = CASE WHEN ( id1 = ? AND id2 = ? ) THEN name WHEN ( id1 = ? AND id2 = ?) THEN ? WHEN ( id1 = ? AND id2 = ?) THEN ? end WHERE (id1,id2) in ( ( ?,? ),( ?,? ),( ?,? ) )
17:31:55.930 [main] DEBUG i.m.m.T.updateListSelective - ==> Parameters: 1(Long), 3(Long), 1(Long), 1(Long), 1(Long), 1(Long), 1(Long), 2(Long), 1(Long), 1(Long), 3(Long), 3(Long), 1(Long), 1(Long), 1(Long), 1(Long), 2(Long), 2(Long), 1(Long), 3(Long), 1(Long), 1(Long), 测试0(String), 1(Long), 2(Long), 测试1(String), 1(Long), 3(Long), 1(Long), 1(Long), 1(Long), 2(Long)
17:31:55.932 [main] DEBUG i.m.m.T.updateListSelective - <== Updates: 3