Mybatis 拦截器
in JavaDevelop with 0 comment

Mybatis 拦截器

in JavaDevelop with 0 comment

Mybatis 拦截器

简介:

Mybatis框架提供的一个功能

能够在Mapper接口方法运行之前或之后添加额外代码的功能

之前我们通过设置,实现将运行的sql语句输出到控制台的效果,就是拦截器实现的

我们也可以简单的进行一个类似的演示

首先,要想能够成功的拦截Mybatis中mapper运行的sql语句

需要先在Spring中设置相关的代码

步骤1:编写拦截器

// Mybatis拦截器测试类
@Slf4j
// Mybatis拦截器配置声明用的注解
// 可以配置拦截多个jdbc中的对象
@Intercepts({@Signature(
        type = StatementHandler.class,
        method = "prepare",
        args = {Connection.class,Integer.class}
)})
public class MyInterceptor implements Interceptor {
    // Mybatis拦截器方法
    // invocation 就是要运行的目标(这里就是sql语句)
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        log.info("进入拦截器,准备拦截sql语句");
        // 从参数invocation中获得要运行的sql语句对象BoundSql
        BoundSql boundSql=((StatementHandler)invocation.getTarget())
                                        .getBoundSql();
        // 从boundSql中获取sql语句
        String sql=boundSql.getSql();
        log.info("要运行的原sql语句为:{}",sql);
        // 下面可以将sql语句进行更改
        sql=sql+" and 1=1";
        log.info("变更后的sql语句:{}",sql);
        // 利用反射强制赋值,将boundSql中的sql属性变化
        reflectUpdateSql(boundSql,"sql",sql);
        
        return invocation.proceed();
    }

    // 需要定义个方法,能够将sql语句进行改写
    // 但是sql语句已经在invocation我么需要利用反射,将其中的属性改写
    private void reflectUpdateSql(BoundSql boundSql,
                                  String attrName,String attrValue)
            throws NoSuchFieldException, IllegalAccessException {
        // 这个方法目标是将boundSql对象的sql强制赋值赋值
        // 反射的属性类
        Field field=boundSql.getClass().getDeclaredField(attrName);
        // 设置属性可强制赋值 设置之后就不是私有属性了
        field.setAccessible(true);
        // 将准备好的值赋值到这个属性中
        field.set(boundSql,attrValue);
    }
    // User 类   User类中有个私有属性password  没有getset方法
    // 反射是可以强制给password属性赋值的
    // BoundSql相当于User对象
    // attrName相当于password属性
    // attrValue相当于我们要强制付给属性的值
    
}

步骤2:

将拦截器设置在SpringBoot框架下使其生效

config包中

//这个类是配置Mybatis拦截器生效的配置类
@Configuration
// 配置Mybatis拦截器生效的固定代码
@AutoConfigureAfter(MybatisAutoConfiguration.class)
public class InterceptorConfig {
    // 获得Mybatis的会话管理器
    // Mybatis会话管理器就是执行连接操作数据库的核心类
    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;

    // 下面方法是将Mybatis会话管理器中所有连接和我们编写的拦截器关联,使拦截器生效
    @PostConstruct
    public void addInterceptors(){
        // 实例化我们编写的拦截器
        Interceptor interceptor=new MyInterceptor();
        for (SqlSessionFactory factory:sqlSessionFactoryList){
            factory.getConfiguration().addInterceptor(interceptor);
        }
    }
}