添加拦截器修改mybatis-plus SQL实现查询出被逻辑删除的数据

添加拦截器修改mybatis-plus SQL实现查询出被逻辑删除的数据

出现的问题

第一次使用springboot+mybatis-plus开发项目,先通过逆向工程生成了所有的文件,但发现查询的时候mybatis默认把被逻辑删除的数据排除掉,这让我很苦恼,因为我想通过逻辑删除来实现用户的状态。这样导致我无法实现我想要的效果

思考

我上网搜了很多帖子,发现网友提供了两种方法

1.在表中再添加一个状态的字段来实现用户状态的判断
2.手写sql语句,根据自己的需求来编写。

这两种方法对于我来说都不适用,因为我有几十张表,如果都修改,那我得掉多少根头发 /(ㄒoㄒ)/~~

于是我继续搜索,发现mybatis-plus提供了一个拦截器接口,可以通过这个接口实现对sql语句的拦截,这样就可以将delId条件进行删除或者修改了

废话不多说了,直接上代码

代码

package com.jcy.stuhelp.common.handler;


import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.Properties;

/**
 * mybatis拦截器
 * 对所有sql语句进行监视,修改
 */
@Slf4j
@Component
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class SqlModifyInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("====SqlModifyInterceptor======");
        System.out.println("====SqlModifyInterceptor======");
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        //通过MetaObject优雅访问对象的属性,这里是访问statementHandler的属性;:MetaObject是Mybatis提供的一个用于方便、
        //优雅访问对象属性的对象,通过它可以简化代码、不需要try/catch各种reflect异常,同时它支持对JavaBean、Collection、Map三种类型对象的操作。
        MetaObject metaObject = MetaObject
                .forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,
                        new DefaultReflectorFactory());
        //先拦截到RoutingStatementHandler,里面有个StatementHandler类型的delegate变量,其实现类是BaseStatementHandler,然后就到BaseStatementHandler的成员变量mappedStatement
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        //id为执行的mapper方法的全路径名,如com.uv.dao.UserMapper.insertUser
        String id = mappedStatement.getId();
        log.info("id为执行的mapper方法的全路径名:" + id);
        //sql语句类型 select、delete、insert、update
        String sqlCommandType = mappedStatement.getSqlCommandType().toString();
        log.info("sql语句类型:" + sqlCommandType);
        BoundSql boundSql = statementHandler.getBoundSql();
        /**
        这些代码是我在网上复制别人的,然后进行了一些小的修改,
        其中log.info()是我为了监控sql的运行情况而添加的代码,不需要可以删除,
        上面部分我不知道是不是必须的,所以我也没有删,下面是我主要修改的地方
        **/
        //获取到原始sql语句
        String sql = boundSql.getSql();
        log.info("拦截的sql语句:" + sql);
        //可以先打印出原始的sql语句,然后根据实际情况修改,我个人建议是下面这样修改
        //只在原sql上添加条件而不是删除条件
        sql=sql.replace("DEL_ID=0 ","DEL_ID=0 OR DEL_ID=1 ");
        log.info("修改之后的sql:" + sql);
        //通过反射修改sql语句
        //下面类似于替换sql
        Field field = boundSql.getClass().getDeclaredField("sql");
        field.setAccessible(true);
        field.set(boundSql, sql);
        return invocation.proceed();
    }

	/**
	下面这两个咱也不知道有没有用,就直接复制粘贴上来了
	**/
    @Override
    public Object plugin(Object target) {
        System.out.println("-----------------------------plugin-------------------------");
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        System.out.println("====setProperties======");
    }
}

结语

目前是跑通的,并且得到了我想要的数据。

如果大家有什么看法可以留言我们一起探讨。
纯属小白操作,如果有大佬看见了,也希望可以指出一些错误的地方。

最后,如果对你有帮助,请点个赞再走吧😀

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis-Plus是一个基于MyBatis的增强工具,提供了许多便捷的功能,其中包括数据拦截器(Data Interceptor)。 数据拦截器MyBatis-Plus提供的一个特性,用于在SQL语句执行前后对数据进行拦截和处理。通过数据拦截器,可以在执行SQL之前对参数进行修改,或者在执行SQL之后对结果进行处理。 使用数据拦截器可以实现一些常见的需求,比如对敏感字段进行加密解密、对某些特定条件进行数据过滤等。 要使用数据拦截器,首先需要创建一个实现了`com.baomidou.mybatisplus.core.plugins.Interceptor`接口的拦截器类。然后,在MyBatis的配置文件中配置该拦截器: ```xml <configuration> <plugins> <plugin interceptor="com.example.MyInterceptor"/> </plugins> </configuration> ``` 其中`com.example.MyInterceptor`是你自定义的拦截器类的全限定名。 在自定义的拦截器类中,你可以通过重写`intercept`方法来实现SQL执行前后的处理逻辑。`intercept`方法接收一个`Invocation`对象作为参数,通过该对象可以获取到SQL语句、参数等相关信息。 ```java public class MyInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 在SQL执行前的处理逻辑 // ... // 执行SQL Object result = invocation.proceed(); // 在SQL执行后的处理逻辑 // ... return result; } } ``` 需要注意的是,如果你使用的是Spring Boot,可以通过`@Bean`注解将拦截器类注入到Spring容器中。如果是非Spring Boot项目,则需要在MyBatis的配置文件中显式配置拦截器。 以上就是使用MyBatis-Plus数据拦截器的基本介绍,希望对你有所帮助。如有更多问题,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值