mybatis-plus批量逻辑删除,并填充字段

 

 

用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)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章