Mybatis 自定义拦截器与插件开发

本文详细介绍了Mybatis的自定义拦截器与插件开发,包括`Interceptor`接口中的`intercept`、`plugin`和`setProperties`方法的用途。重点解析了`wrap`方法如何通过JDK动态代理实现逻辑增强。通过分析mybatis的拦截器执行顺序,展示了拦截器在SQL监控、分页查询、公共字段赋值和数据权限过滤等方面的应用。并讨论了插件的定义与注册,包括`@Intercepts`注解的使用和在`SqlSessionFactory`或配置文件中的注册方式。最后,通过Executor、StatementHandler和ResultSetHandler的拦截器示例,阐述了如何利用拦截器实现SQL监控、动态修改SQL分页和结果集脱敏等功能。
摘要由CSDN通过智能技术生成

Object intercept(Invocation invocation) throws Throwable;

default Object plugin(Object target) {

return Plugin.wrap(target, this);

}

default void setProperties(Properties properties) {

// NOP

}

}

  • intercept :在拦截目标对象的方法时,实际执行的增强逻辑,我们一般在该方法中实现自定义逻辑

  • plugin :用于返回原生目标对象或它的代理对象,当返回的是代理对象的时候,会调用 intercept 方法

  • setProperties :可以用于读取配置文件中通过 property 标签配置的一些属性,设置一些属性变量

看一下 plugin 方法中的 wrap 方法源码:

public static Object wrap(Object target, Interceptor interceptor) {

Map<Class<?>, Set> signatureMap = getSignatureMap(interceptor);

Class<?> type = target.getClass();

Class<?>[] interfaces = getAllInterfaces(type, signatureMap);

if (interfaces.length > 0) {

return Proxy.newProxyInstance(

type.getClassLoader(),

interfaces,

new Plugin(target, interceptor, signatureMap));

}

return target;

}

可以看到,在 wrap 方法中,通过使用jdk动态代理的方式,生成了目标对象的代理对象,在执行实际方法前,先执行代理对象中的逻辑,来实现的逻辑增强。以拦截 Executor 的 query 方法为例,在实际执行前会执行拦截器中的 intercept 方法:

在mybatis中,不同类型的拦截器按照下面的顺序执行:

Executor -> StatementHandler -> ParameterHandler -> ResultSetHandler

以执行 query 方法为例对流程进行梳理,整体流程如下:

1、 Executor 执行 query() 方法,创建一个 StatementHandler 对象

2、 StatementHandler 调用 ParameterHandler 对象的 setParameters() 方法

3、 StatementHandler 调用 Statement 对象的 execute() 方法

4、 StatementHandler 调用 ResultSetHandler 对象的 handleResultSets() 方法,返回最终结果

拦截器能实现什么

========

在对mybatis拦截器有了初步的认识后,来看一下拦截器被普遍应用在哪些方面:

  • sql 语句执行监控可以拦截执行的sql方法,可以打印执行的sql语句、参数等信息,并且还能够记录执行的总耗时,可供后期的sql分析时使用

  • sql 分页查询mybatis中使用的 RowBounds 使用的内存分页,在分页前会查询所有符合条件的数据,在数据量大的情况下性能较差。通过拦截器,可以做到在查询前修改sql语句,提前加上需要的分页参数

  • 公共字段的赋值在数据库中通常会有 createTime , updateTime 等公共字段,这类字段可以通过拦截统一对参数进行的赋值,从而省去手工通过 set 方法赋值的繁琐过程

  • 数据权限过滤在很多系统中,不同的用户可能拥有不同的数据访问权限,例如在多租户的系统中,要做到租户间的数据隔离,每个租户只能访问到自己的数据,通过拦截器改写sql语句及参数,能够实现对数据的自动过滤

除此之外,拦截器通过对上述的4个阶段的介入,结合我们的实际业务场景,还能够实现很多其他功能。

插件定义与注册

=======

在我们自定义的拦截器类实现了 Interceptor 接口后,还需要在类上添加 &#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值