Mybatis的拦截器Interceptor
通过织入拦截器,在不同节点修改一些执行过程中的关键属性,从而影响SQL的生成、执行和返回结果,拦截sql,达到不入侵原有代码业务处理一些东西,比如:分页操作,数据权限过滤操作,SQL执行时间性能监控等
拦截对象类型
mybatis拦截器可以拦截如下4种对象中的方法:
Executor sql的内部执行器
ParameterHandler 拦截参数的处理
StatementHandler 拦截sql的构建
ResultSetHandler 拦截结果的处理
核心对象
Configuration
初始化基础配置,比如MyBatis的别名等,一些重要的类型对象,如插件,映射器,ObjectFactory和typeHandler对象,MyBatis所有的配置信息都维持在Configuration对象之中
SqlSessionFactory
SqlSession工厂。
SqlSession
作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要的数据库增删改查功能。
Executor
MyBatis的内部执行器,它负责调用StatementHandler操作数据库,并把结果集通过ResultSetHandler进行自动映射,另外,它还处理二级缓存的操作。
StatementHandler
封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合
ParameterHandler
负责对用户传递的参数转换成JDBC Statement 所需要的参数
ResultSetHandler
负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;
TypeHandler
负责java数据类型和jdbc数据类型之间的映射和转换
MappedStatement
MappedStatement维护了一条mapper.xml文件里面 select 、update、delete、insert节点的封装
SqlSource
负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回
BoundSql
表示动态生成的SQL语句以及相应的参数信息
自定义mybatis的拦截器步骤:
定义一个实现org.apache.ibatis.plugin.Interceptor接口的拦截器类,并实现其中的方法。
添加@Intercepts注解,写上需要拦截的对象和方法,以及方法参数。
在mybatis的全局配置xml中配置插件plugin,注册拦截器
注册拦截器
注册拦截器是通过在Mybatis配置文件中plugins元素下的plugin元素来进行的。一个plugin对应着一个拦截器,在plugin元素下面我们可以指定若干个property子元素。Mybatis在注册定义的拦截器时会先把对应拦截器下面的所有property通过Interceptor的setProperties方法注入给对应的拦截器。
注解
@Intercepts:标识该类是一个拦截器;
@Signature:指明自定义拦截器需要拦截哪一个类型,哪一个方法;
type:对应四种类型中的一种;
method:对应接口中的哪类方法(因为可能存在重载方法);
args:是method中方法的入参
org.apache.ibatis.plugin.Interceptor接口
主要是实现下面几个方法:intercept(Invocation invocation)、plugin(Object target) 、setProperties(Properties properties);
intercept(Invocation invocation)方法
进行拦截的时候要执行的方法。
Invocation中有三个参数。
target:StatementHandler; //被代理对象
method :query; //代理方法
args[]:Statement st,ResultHandler rh //方法参数
@Override
public Object intercept(Invocation invocation) throws Throwable {
//这里不管几个结果都是返回一个list,强转成list即可
Object proceed = invocation.proceed();
System.out.println(proceed);
return proceed;
}
plugin方法
插件用于封装目标对象的,通过该方法我们可以返回目标对象本身,也可以返回一个它的代理,可以决定是否要进行拦截进而决定要返回一个什么样的目标对象,官方提供了示例:"return Plugin.wrap(target, this);";
setProperties方法
如果我们拦截器需要用到一些变量参数,而且这个参数是支持可配置的,类似Spring中的@Value("${}")从application.properties文件获取自定义变量属性,这个时候我们就可以使用这个方法。