通过foreach批量更新
1、pom
<!-- tk.mybatis -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
2、注解接口 -> MyInsertListSelectiveMapper.java
package com.sundear.base.mybatis.tk.base;
import com.sundear.base.mybatis.tk.provider.MyUpdateListForeachProvider;
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批量修改 foreach 效率其实很可观
*/
@RegisterMapper
public interface MyUpdateListForeachMapper<T> {
/**
* 自定义,根据id批量修改 foreach 效率其实很可观.
* 注意:
* 1、该方法返回不了被修改成功的条数:0-》全部未修改成功 1—》全部修改成功or部分修改成功
* 2、使用这个方法需要关闭防火墙(若有)-》spring.datasource.druid.filters中不能又wall参数
* 3、sql url中需要有 &allowMultiQueries=true 参数
*
* @param var1
* @return 0-》全部未修改成功 1—》全部修改成功or部分修改成功
*/
@UpdateProvider(
type = MyUpdateListForeachProvider.class,
method = "dynamicSQL"
)
int myUpdateListForeachByPrimaryKey(@Param("records") List<T> var1);
}
3、MyUpdateListForeachProvider.java
package com.sundear.base.mybatis.tk.provider;
import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.annotation.Version;
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 tk.mybatis.mapper.version.VersionException;
import java.util.Iterator;
import java.util.Set;
/**
* @Author: 秀丽
* @Date: 2021/5/25 17:43
* @description 自定义,根据id批量修改 foreach 效率其实很可观
*/
public class MyUpdateListForeachProvider extends MapperTemplate {
public MyUpdateListForeachProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
super(mapperClass, mapperHelper);
}
public String myUpdateListForeachByPrimaryKey(MappedStatement ms) {
Class<?> entityClass = this.getEntityClass(ms);
StringBuilder sql = new StringBuilder();
sql.append("<bind name=\"listNotEmptyCheck\" value=\"@tk.mybatis.mapper.util.OGNL@notEmptyCollectionCheck(records, '" + ms.getId() + " 方法参数为空')\"/>");
sql.append("<foreach collection=\"records\" item=\"record\" index=\"index\" open=\"\" close=\"\" separator=\";\">");
sql.append(SqlHelper.updateTable(entityClass, this.tableName(entityClass)));
sql.append(SqlHelper.updateSetColumns(entityClass, "record", true, this.isNotEmpty()));
sql.append(wherePKColumns(entityClass, "record", true));
sql.append("</foreach>");
return sql.toString();
}
/**
* 需要重写SqlHelper中的方法,因为SqlHelper的useVersion在foreach中不能用。
*
* @param entityClass
* @param entityName
* @param useVersion
* @return
*/
private String wherePKColumns(Class<?> entityClass, String entityName, boolean useVersion) {
StringBuilder sql = new StringBuilder();
boolean hasLogicDelete = SqlHelper.hasLogicDeleteColumn(entityClass);
sql.append("<where>");
Set<EntityColumn> columnSet = EntityHelper.getPKColumns(entityClass);
Iterator var6 = columnSet.iterator();
while (var6.hasNext()) {
EntityColumn column = (EntityColumn) var6.next();
sql.append(" AND ").append(column.getColumnEqualsHolder(entityName));
}
if (useVersion) {
sql.append(whereVersion(entityClass, entityName));
}
if (hasLogicDelete) {
sql.append(SqlHelper.whereLogicDelete(entityClass, false));
}
sql.append("</where>");
return sql.toString();
}
private String whereVersion(Class<?> entityClass, String entityName) {
Set<EntityColumn> columnSet = EntityHelper.getColumns(entityClass);
boolean hasVersion = false;
String result = "";
Iterator var4 = columnSet.iterator();
while (var4.hasNext()) {
EntityColumn column = (EntityColumn) var4.next();
if (column.getEntityField().isAnnotationPresent(Version.class)) {
if (hasVersion) {
throw new VersionException(entityClass.getCanonicalName() + " 中包含多个带有 @Version 注解的字段,一个类中只能存在一个带有 @Version 注解的字段!");
}
hasVersion = true;
result = " AND " + column.getColumnEqualsHolder(entityName);
}
}
return result;
}
}
3、创建一个基础mapper继承我们自定义的接口 -》 MyBaseMapper.java
这个接口用以继承以后我们所写的所有tk自定义接口
package com.sundear.base.mybatis;
import com.sundear.base.mybatis.tk.base.MyUpdateListForeachMapper;
/**
* @Author: 秀丽
* @Date: 2021/5/8 17:41
* @description 继承自定义的方法
*/
public interface MyBaseMapper<T> extends MyUpdateListForeachMapper<T>{
}
4、实体类mapper继承MyBaseMapper.java
package com.sundear.dao;
import com.sundear.pojo.TbTest;
import com.sundear.tk.MyBaseMapper;
import org.apache.ibatis.annotations.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
/**
* @Author: xiu
* @Date: 2021/5/25 10:25
* @description
*/
@Mapper
public interface TbTestMapper extends
tk.mybatis.mapper.common.Mapper<TbTest>,
MySqlMapper<TbTest>,
//这个就是我们自定义的通用mapper
MyBaseMapper<TbTest> {
}
5、然后我们就可以用实体类的mapper直接调用 myUpdateListForeachByPrimaryKey(List<T> var1) 方法去批量更新了list了。