MyBatis-Plus 3.1.0版本逻辑删除不生效

问题描述

接手的Spring Boot老项目,使用的MyBatis-Plus版本是3.1.0
maven配置:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.1.0</version>
</dependency>

实体类有添加@TableLogic注解,一般来说这样就能实现逻辑删除的功能了,官网上面的操作也是这样。https://baomidou.com/guides/logic-delete/
但实际测试逻辑删除的条件没生效,依旧使用的物理删除

解决方案

升级版本(❌)

尝试将MyBatis-Plus升级到3.5.12,但新旧版本的代码生成器不兼容,编译会报错

配置全局逻辑删除属性(❌)

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: is_deleted # 全局逻辑删除字段名
      logic-delete-value: 1 # 逻辑已删除值。可选,默认值为 1
      logic-not-delete-value: 0 # 逻辑未删除值。可选,默认值为 0

测试依旧没有生效

新增配置类注入逻辑删除实现(✔)

import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig {

    /**
     * 注入逻辑删除
     * @return
     */
    @Bean
    public ISqlInjector sqlInjector(){
        return new LogicSqlInjector();
    }
}

源码解析

在询问了AI以及上网搜索其他解决方案都无果后,我尝试去阅读逻辑删除相关的源码
其中最主要的类是AbstractSqlInjector,项目启动时会对所有mapper进行解析并生成CURD方法,调用的就是AbstractSqlInjector里的inspectInject方法

    @Override
    public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
        String className = mapperClass.toString();
        Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
        if (!mapperRegistryCache.contains(className)) {
            List<AbstractMethod> methodList = this.getMethodList();
            Assert.notEmpty(methodList, "No effective injection method was found.");
            // 循环注入自定义方法
            Class<?> modelClass = extractModelClass(mapperClass);
            if (modelClass != null) {
                TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass);
                methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));
            }
            mapperRegistryCache.add(className);
            /*
             * 初始化 SQL 解析
             */
            if (GlobalConfigUtils.getGlobalConfig(builderAssistant.getConfiguration()).isSqlParserCache()) {
                SqlParserHelper.initSqlParserInfoCache(mapperClass);
            }
        }
    }

这个方法里关键的是这一行,这一行就是获取抽象的CURD方法

List<AbstractMethod> methodList = this.getMethodList();

按住CtrlAlt键,然后鼠标点击这个getMethodList方法,会发现这个抽象方法有2个实现,一个是DefaultSqlInjector,一个是LogicSqlInjector
image

其中DefaultSqlInjector这个是默认的实现,实现的是物理删除而不是逻辑删除

package com.baomidou.mybatisplus.core.injector;

import com.baomidou.mybatisplus.core.injector.methods.*;

import java.util.List;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;


/**
 * SQL 默认注入器
 *
 * @author hubin
 * @since 2018-04-10
 */
public class DefaultSqlInjector extends AbstractSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList() {
        return Stream.of(
            new Insert(),
            new Delete(),
            new DeleteByMap(),
            new DeleteById(),
            new DeleteBatchByIds(),
            new Update(),
            new UpdateById(),
            new SelectById(),
            new SelectBatchByIds(),
            new SelectByMap(),
            new SelectOne(),
            new SelectCount(),
            new SelectMaps(),
            new SelectMapsPage(),
            new SelectObjs(),
            new SelectList(),
            new SelectPage()
        ).collect(toList());
    }
}

LogicSqlInjector实现的是逻辑删除

package com.baomidou.mybatisplus.extension.injector;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.AbstractSqlInjector;
import com.baomidou.mybatisplus.core.injector.methods.Insert;
import com.baomidou.mybatisplus.extension.injector.methods.*;

import java.util.List;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * SQL 逻辑删除注入器
 *
 * @author hubin
 * @since 2018-06-12
 */
public class LogicSqlInjector extends AbstractSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList() {
        return Stream.of(
            new Insert(),
            new LogicDelete(),
            new LogicDeleteByMap(),
            new LogicDeleteById(),
            new LogicDeleteBatchByIds(),
            new LogicUpdate(),
            new LogicUpdateById(),
            new LogicSelectById(),
            new LogicSelectBatchByIds(),
            new LogicSelectByMap(),
            new LogicSelectOne(),
            new LogicSelectCount(),
            new LogicSelectMaps(),
            new LogicSelectMapsPage(),
            new LogicSelectObjs(),
            new LogicSelectList(),
            new LogicSelectPage()
        ).collect(toList());
    }
}

启动项目的时候进行debug,发现每次进入的都是默认实现DefaultSqlInjector,所以才导致逻辑删除没有生效。因此解决方案也就出来了,新增一个配置类,然后将注入逻辑删除的实现类

posted @ 2025-07-14 15:35  NineString  阅读(161)  评论(0)    收藏  举报