Mybatis之插件开发
一 概述
- MyBatis在四大对象的创建过程中,都会有插件进行介入。插件可以利用动态代理机制一层层的包装目标对象,而实现在目标对象执行目标方法之前进行拦截的效果
- MyBatis 允许在已映射语句执行过程中的某一点进行拦截调用。
- 默认情况下,MyBatis 允许使用插件来拦截的方法调 用包括:
(1) Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
(2)ParameterHandler (getParameterObject, setParameters)
(3) ResultSetHandler (handleResultSets, handleOutputParameters)
(4)StatementHandler (prepare, parameterize, batch, update, query)
二 插件开发
- 开发步骤
(1)编写插件实现Interceptor接口,并使用 @Intercepts注解完成插件签名
(2)在全局配置文件中注册插件
三 插件原理
- 按照插件注解声明,按照插件配置顺序调用插件plugin方 法,生成被拦截对象的动态代理
- 多个插件依次生成目标对象的代理对象,层层包裹,先声 明的先包裹;形成代理链
- 目标方法执行时依次从外到内执行插件的intercept方法
- 多个插件情况下,我们往往需要在某个插件中分离出目标 对象。可以借助MyBatis提供的SystemMetaObject类来进行获 取最后一层的h以及target属性的值
四 Interceptor接口
(1) intercept方法:拦截目标方法
(2)plugin方法:生成动态代理对象,可以使用MyBatis提 供的Plugin类的wrap方法
(3)setProperties方法:注入插件配置时设置的属性
(4)常用代码
//1、分离代理对象
//由于会形成多次代理,所以需要通过一个 while 循环分离出最终被代理对象,从而方便提取信息
MetaObject metaObject = SystemMetaObject. forObject(target);
while (metaObject.hasGetter("h")) {
Object h = metaObject.getValue("h");
metaObject = SystemMetaObject. forObject(h);
}
//2、获取到代理对象中包含的被代理的真实对象
Object obj = metaObject.getValue("target");
//3、获取被代理对象的MetaObject方便进行信息提取
MetaObject forObject = SystemMetaObject. forObject(obj);