通过When Case批量更新
1、pom
<!-- tk.mybatis -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
2、注解接口 -> MyUpdateListWhenCaseMapper.java
package com.sundear.base.mybatis.tk.base;
import com.sundear.base.mybatis.tk.provider.MyUpdateListWhenCaseProvider;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.UpdateProvider;
import tk.mybatis.mapper.annotation.RegisterMapper;
import java.util.List;
/**
* @Author: 秀丽
* @Date: 2021/5/25 17:43
* @description 自定义,根据id批量修改 when case 效率其实很慢
*/
@RegisterMapper
public interface MyUpdateListWhenCaseMapper<T> {
/**
* 自定义,根据id批量修改 when case 效率其实很慢
* @param var1
* @param var2
* @return
*/
@UpdateProvider(
type = MyUpdateListWhenCaseProvider.class,
method = "dynamicSQL"
)
int myUpdateListWhenCaseByPrimaryKey(@Param("records") List<T> var1, @Param("example") Object var2);
}
3、MyUpdateListWhenCaseProvider.java
package com.sundear.base.mybatis.tk.provider;
import com.sundear.model.exception.ServiceException;
import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
import java.util.Set;
/**
* @Author: 秀丽
* @Date: 2021/5/25 17:43
* @description 自定义,根据id批量修改
*/
public class MyUpdateListWhenCaseProvider extends MapperTemplate {
public MyUpdateListWhenCaseProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
super(mapperClass, mapperHelper);
}
public String myUpdateListWhenCaseByPrimaryKey(MappedStatement ms) {
Class<?> entityClass = this.getEntityClass(ms);
//tableName
String tableName = SqlHelper.getDynamicTableName(entityClass, this.tableName(entityClass), "example");
StringBuilder sql = new StringBuilder();
sql.append("<bind name=\"listNotEmptyCheck\" value=\"@tk.mybatis.mapper.util.OGNL@notEmptyCollectionCheck(records, '" + ms.getId() + " 方法参数为空')\"/>");
sql.append("UPDATE ");
sql.append(tableName);
sql.append(" <set>");
//实体类所有字段
Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
//实体类对应id字段
EntityColumn idColumn = columnList
.stream()
.filter(tempColumn -> tempColumn.isId()).findFirst()
.orElseThrow(() -> new ServiceException("实体类id不存在"));
columnList.stream().forEach(tempColumn -> {
if (!tempColumn.isId()) {
appendSetInfo(sql, tempColumn, idColumn, tableName);
}
});
sql.append("</set>");
sql.append(SqlHelper.updateByExampleWhereClause());
return sql.toString();
}
/**
* @param sql
* @param column update字段
* @param idColumn id字段
*/
private void appendSetInfo(StringBuilder sql, EntityColumn column, EntityColumn idColumn, String tableName) {
sql.append("<trim prefix=\"`" + column.getColumn() + "` = case " + idColumn.getColumn() + "\" suffix=\"end , \">");
sql.append("<foreach collection=\"records\" item=\"record\">");
sql.append("<if test=\"record." + column.getEntityField().getName() + " !=null\">");
sql.append(" WHEN #{record." + idColumn.getEntityField().getName() + "} THEN #{record." + column.getEntityField().getName() + "} ");
sql.append("</if>");
sql.append("<if test=\"record." + column.getEntityField().getName() + " ==null\">");
sql.append(" WHEN #{record." + idColumn.getEntityField().getName() + "} THEN " + tableName + "." + column.getColumn() + " ");
sql.append("</if>");
sql.append("</foreach>");
sql.append("</trim>");
}
}
3、用我们的基础mapper继承我们上述接口 -》上篇文章已经创建过这个类
package com.sundear.base.mybatis;
import com.sundear.base.mybatis.tk.base.MyUpdateListForeachMapper;
import com.sundear.base.mybatis.tk.base.MyUpdateListWhenCaseMapper;
/**
* @Author: 秀丽
* @Date: 2021/5/8 17:41
* @description 继承自定义的方法
*/
public interface MyBaseMapper<T> extends
MyUpdateListForeachMapper<T>,
MyUpdateListWhenCaseMapper<T> {
}
4、然后我们就可以用实体类的mapper直接调用 myUpdateListWhenCaseByPrimaryKey(List<T> var1) 方法去批量更新了list了
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class RunTest {
@Resource
private TbRoleMapper tbRoleMapper;
@Resource
private TbTestMapper tbTestMapper;
@Test
public void test2() {
List<TbTest> list = new ArrayList<>();
for (int i = 0; i < 4; i++) {
list.add(TbTest.builder().value(""+i).id(IdWorker.getIdWorker().nextIdStr()).build());
}
//方式一 foreach
tbTestMapper.myUpdateListForeachByPrimaryKey(list);
//方式二 when case
Example example = new Example(TbTest.class);
example.createCriteria()
.andIn(TbTest.Fields.id,list.stream().map(TbTest::getId).collect(Collectors.toList()));
tbTestMapper.myUpdateListWhenCaseByPrimaryKey(list,example);
}
}