2. 如何让mybatis-plus的逻辑删除注解@TableLogic临时失效

文章目录

  • 如何让mybatis-plus的逻辑删除注解@TableLogic临时失效
    • [1. 场景复现](#1. 场景复现)
      • [1.1 controller代码](#1.1 controller代码)
      • [1.2 service层代码](#1.2 service层代码)
      • [1.3 entity代码](#1.3 entity代码)
    • [2. 问题分析](#2. 问题分析)
    • [3. 解决方案](#3. 解决方案)
      • [3.1 说明](#3.1 说明)
      • [3.2 核心代码](#3.2 核心代码)
      • [3.3 service方法对应修改为](#3.3 service方法对应修改为)
      • [3.4 运行结果](#3.4 运行结果)

如何让mybatis-plus的逻辑删除注解@TableLogic临时失效

1. 场景复现

1.1 controller代码

复制代码
@GetMapping("/getSpacexTable")
public String getSpacexTable(){
    List<SpacexTable> list = spacexTableService.queryAll();
    return JSON.toJSONString(list);
}

1.2 service层代码

复制代码
@Override
public List<SpacexTable> queryAll() {
    List<SpacexTable> list = list();
    return list;
}

1.3 entity代码

复制代码
@Data
@TableName(value ="spacex_table")
public class SpacexTable implements Serializable {
    @TableId
    private String id;
    private String name;
    @TableLogic
    private Integer isDel;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}

2. 问题分析

当我们正常调用接口时,sql查询日志为

复制代码
SELECT id,name,is_del FROM spacex_table WHERE is_del=0

数据库数据记录为:

接口调用结果为

复制代码
[{"id":"1","isDel":0,"name":"小张"},{"id":"3","isDel":0,"name":"小杨"}]

可见逻辑删除注解已生效,is_del=1的小李没有查询出来

3. 解决方案

3.1 说明

  1. 我们让当前查询的逻辑删除失效时,不应影响其他查询活动,所以我们我们需要在线程上打上标识,区分是否执行逻辑删除
  2. 因为使用了mybatis-plus框架,所以可以通过拦截器来实现,在适当方法处,将sql语句中的逻辑删除替换掉即可

3.2 核心代码

复制代码
@Slf4j
@Component
// 拦截StatementHandler的prepare方法,改变编译的SQL语句
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class LogicDeletenterceptor implements Interceptor {
    
    // 通过ThreadLocal给当前线程打上标识
    public static ThreadLocal<Boolean> logicDelete = new ThreadLocal();
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        log.info("====SqlModifyInterceptor======(" + logicDelete.get() + ")=====");
        // 判断线程标识
        if (!Boolean.FALSE.equals(logicDelete.get())) {
            return invocation.proceed();
        }
        StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget());
        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {
            return invocation.proceed();
        }
        BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
        String sql = boundSql.getSql();
        log.info("origin sql:" + sql);
        // TODO 在这里替换字段,改成不影响结果的条件即可
        sql = sql.replace("is_del=0","1=1").replace("del_number=0", "1=1");
        metaObject.setValue("delegate.boundSql.sql",sql);
        log.info("modify sql:" + sql);
        return invocation.proceed();
    }
    
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {}
}

3.3 service方法对应修改为

复制代码
@Override
public List<SpacexTable> queryAll() {
    // 开启逻辑删除失效    
    LogicDeletenterceptor.logicDelete.set(false);
    List<SpacexTable> list = list();
    // 关闭逻辑删除失效
    LogicDeletenterceptor.logicDelete.remove();
    return list;
}

3.4 运行结果

sql查询日志为

复制代码
SELECT id,name,is_del FROM spacex_table WHERE 1=1

接口调用结果为

复制代码
[{"id":"1","isDel":0,"name":"小张"},{"id":"2","isDel":1,"name":"小李"},{"id":"3","isDel":0,"name":"小杨"}]

可见逻辑删除is_del=1的小李也被查询出来了

相关推荐
爱的叹息1 小时前
Spring和Spring Boot集成MyBatis的完整对比示例,包含从项目创建到测试的全流程代码
spring boot·spring·mybatis
与秋逐鹿¥9 小时前
在Mybatis中为什么要同时指定扫描mapper接口和 mapper.xml 文件,理论单独扫描 xml 文件就可以啊
java·tomcat·mybatis
爱的叹息9 小时前
MyBatis 插件开发的完整详细例子
mybatis
Minyy1115 小时前
SpringBoot程序的创建以及特点,配置文件,LogBack记录日志,配置过滤器、拦截器、全局异常
xml·java·spring boot·后端·spring·mybatis·logback
北辰浮光1 天前
[Mybatis-plus]
java·开发语言·mybatis
方圆想当图灵1 天前
由 Mybatis 源码畅谈软件设计(七):SQL “染色” 拦截器实战
后端·mybatis·代码规范
毅航1 天前
MyBatis 事务管理:一文掌握Mybatis事务管理核心逻辑
java·后端·mybatis
啊松同学1 天前
【Mybatis】MyBatisPlus的saveBatch真的是批量插入吗?深度解析与性能优化
java·后端·性能优化·mybatis
阿里小阿希1 天前
解决 Spring Boot + MyBatis 项目迁移到 PostgreSQL 后的数据类型不匹配问题
spring boot·postgresql·mybatis
凯酱1 天前
MyBatis-Plus分页插件的使用
java·tomcat·mybatis