接口 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