简说Mybatis插件-Plugin
Mybatis自定义插件-Plugin
文章内容输出来源:拉勾教育Java高薪训练营
Mybatis作为一个应用广泛的优秀的ORM开源框架,这个框架具有强大的灵活性,在四大组件 (Executor、StatementHandler、ParameterHandler、ResultSetHandler)处提供了简单易用的插 件扩 展机制。Mybatis对持久层的操作就是借助于四大核心对象。MyBatis支持用插件对四大核心对象进 行拦 截,对mybatis来说插件就是拦截器,用来增强核心对象的功能,增强功能本质上是借助于底层的 动态 代理实现的,换句话说,MyBatis中的四大对象都是代理对象
Mybatis四大核心组件
- 执行器Executor (update、query、commit、rollback等方法);
- SQL语法构建器StatementHandler (prepare、parameterize、batch、updates query等方 法);
- 参数处理器ParameterHandler (getParameterObject、setParameters方法);
- 结果集处理器ResultSetHandler (handleResultSets、handleOutputParameters等方法);
Mybatis插件原理
1、每个创建出来的对象不是直接返回的,而是interceptorChain.pluginAll(parameterHandler);
2、获取到所有的Interceptor (拦截器)(插件需要实现的接口);调用 interceptor.plugin(target);返 回 target 包装后的对象
3、插件机制,我们可以使用插件为目标对象创建一个代理对象;AOP (面向切面)我们的插件可 以 为四大对象创建出代理对象,代理对象就可以拦截到四大对象的每一个执行;
如何开启插件拦截功能
interceptorChain保存了所有的拦截器(interceptors),是mybatis初始化的时候创建的。调用拦截器链 中的拦截器依次的对目标进行拦截或增强。interceptor.plugin(target)中的target就可以理解为mybatis 中的四大对象。返回的target是被重重代理后的对象
如果我们想要拦截Executor的query方法,那么可以这样定义插件:
1.首先我们需要实现Interceptor
public class MyPlugin implements Interceptor {}
2.重写intercept(),plugin(),setProperties()三个方法
/**
* 拦截方法:只要被拦截目标对象的目标方法被执行时 每次都会执行intercept 方法 方法内可以写入想要执行的逻辑
* @param invocation
* @return
* @throws Throwable
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("对方法进行了增强...");
return invocation.proceed(); //原方法执行
}
/**
* 主要为了把当前的拦截器生成代理存到连接器链(Invocation)中
* @param o
* @return
*/
@Override
public Object plugin(Object o) {
Object wrap = Plugin.wrap(o, this);
return wrap;
}
/**
* 获取配置文件的参数 可以读取sqlMapConfig.xml中的配置
* @param properties
*/
@Override
public void setProperties(Properties properties) {
System.out.println("获取到的配置文件的参数是:"+properties);
}
sqlMapConfig.xml配置如下
<plugins>
<plugin interceptor="com.lxy.plugin.MyPlugin">
<property name="name" value="tom"/>
</plugin>
</plugins>
3.引入注解来实现拦截配置
@Intercepts({}) 注意这是一个数组,可以定义多个@Signature 对多个地方进行拦截
@Signature
type = Executor.class 拦截某个指定的接口
method = “query” 值这个接口中的某个方法
args= {} 拦截方法的入参,因为有方法重载,可以通过方法名和入参来确定是唯一的一个方法
@Intercepts({
@Signature(
type = Executor.class,
method = "query",
args= {MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class}
)
})
至此,简单的mybatis自定义插件功能就好了,快去试试你们的自定义插件把~