用mybatis-plus這個工具一年了,之前邏輯刪除的時候都是使用update語句,更新刪除標識和更新時間,更新人id。後來才發現作者提供了邏輯刪除標識@TableLogic,加上這個註解就可以調用刪除接口直接刪除,但是隻是簡單的將刪除標識字段更新爲刪除狀態。參考了文章
https://blog.csdn.net/qq_39313596/article/details/101039964
知道mybatis-plus作者提供了LogicDeleteByIdWithFill這個裝載器,可以實現邏輯刪除,並更新相關字段。
但這個裝載器實現的是根據id刪除,沒有提供多條刪除的功能。好在作者提供了相關接口,可以自己實現。
所有我將LogicDeleteByIdWithFill和Update兩個裝載器結合,簡單實現了一下
public class LogicBatchDeleteWithFill extends AbstractMethod {
/**
* mapper 對應的方法名
*/
private static final String MAPPER_METHOD = "batchDeleteWithFill";
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
String sql;
SqlMethod sqlMethod = SqlMethod.LOGIC_DELETE;
if (tableInfo.isLogicDelete()) {
List<TableFieldInfo> fieldInfos = tableInfo.getFieldList().stream()
.filter(i -> i.getFieldFill() == FieldFill.UPDATE || i.getFieldFill() == FieldFill.INSERT_UPDATE)
.collect(toList());
if (CollectionUtils.isNotEmpty(fieldInfos)) {
String sqlSet = "SET " + fieldInfos.stream().map(i -> i.getSqlSet(ENTITY_DOT)).collect(joining(EMPTY))
+ tableInfo.getLogicDeleteSql(false, true);
sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), sqlSet,
sqlWhereEntityWrapper(true, tableInfo));
} else {
sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), sqlLogicSet(tableInfo),
sqlWhereEntityWrapper(true, tableInfo));
}
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addUpdateMappedStatement(mapperClass, modelClass, MAPPER_METHOD, sqlSource);
} else {
sqlMethod = SqlMethod.DELETE;
sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(),sqlWhereEntityWrapper(true, tableInfo));
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addDeleteMappedStatement(mapperClass, MAPPER_METHOD, sqlSource);
}
}
}
同樣需要加載到配置裏
public class MySqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> methodList = super.getMethodList();
methodList.add(new LogicDeleteByIdWithFill());
methodList.add(new LogicBatchDeleteWithFill());
return methodList;
}
}
@Bean
public MySqlInjector myLogicSqlInjector() {
return new MySqlInjector();
}
@Data
@TableName("t_student")
public class Student{
@SCFMember(orderId = 1)
@TableId(value = "id", type = IdType.INPUT)
private Long id;
private Integer score;
@TableField(value = "updated_by",fill = FieldFill.UPDATE)
private Long updatedBy;
@TableField(value="updated_time",fill = FieldFill.UPDATE)
private Date updatedTime;
}
public interface StudentMapper extends BaseMapper<Student> {
/**
* 邏輯刪除並填充字段
* @param param
* @return
*/
int deleteByIdWithFill(Studentparam);
/**
* 批量邏輯刪除並填充字段
* @param param
* @return
*/
int batchDeleteWithFill(@Param(Constants.ENTITY)Student param,@Param(Constants.WRAPPER)Wrapper<Student> wrapper);
}
測試如下,特別注意需要在刪除的時候填充字段 需要在實體類加上上自動填充註解 @TableField(fill = FieldFill.UPDATE)。
如果覺得加FieldFill.UPDATE繁瑣,可以重寫上面的sql注入器。
@Test
public void test1() throws Exception {
Student student = new Student ();
student.setUpdatedTime(new Date());
student.setUpdatedBy(2L);
int resultstudent Mapper.batchDeleteWithFill(student , Wrappers.<Student>lambdaQuery().in(Student::getScore,1,2,3));
System.out.println(result);
}
生成的sql如下。
update student set ,update_time='2020-05-16 14:59:03',update_by=2,delete_flag=1
where delete_flag=0 and score in (1,2,3)