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的小李也被查询出来了

相关推荐
弗拉唐43 分钟前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
凌冰_2 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
Elaine2023914 小时前
零碎04 MybatisPlus自定义模版生成代码
java·spring·mybatis
一二小选手4 小时前
【MyBatis】全局配置文件—mybatis.xml 创建xml模板
xml·java·mybatis
刘大浪5 小时前
后端数据增删改查基于Springboot+mybatis mysql 时间根据当时时间自动填充,数据库连接查询不一致,mysql数据库连接不好用
数据库·spring boot·mybatis
蓝染-惣右介7 小时前
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
java·数据库·tomcat·mybatis
武子康8 小时前
Java-07 深入浅出 MyBatis - 一对多模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据库·sql·mybatis·springboot
一二小选手8 小时前
【Mybatis】@Param注解 resultMap手动映射
java·mybatis
郑祎亦11 小时前
Spring Boot 项目 myblog 整理
spring boot·后端·java-ee·maven·mybatis