MyBatis插件开发实战
保留所有版权,请引用而不是转载本文(原文地址 https://yeecode.top/blog/71/ )。
本文将开发一个功能非常简单的MyBatis插件,来了解MyBatis插件的开发过程。我们要开发的插件的功能是:在MyBatis查询列表形式的的结果时,打印出结果的数目。
整个插件的源代码非常简单,我们直接给出,如下面代码所示。
@Intercepts({
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class YeecodeInterceptor implements Interceptor {
private String info;
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 执行原有方法
Object result = invocation.proceed();
// 打印原方法输出结果的数目
System.out.println(info + ":" + ((List) result).size());
// 返回原有结果
return result;
}
@Override
public void setProperties(Properties properties) {
// 为拦截器设置属性
info = properties.get("preInfo").toString();
}
}
MyBatis插件是一个实现了Interceptor接口的类。Interceptor的含义是拦截器,因此我们所说的MyBatis插件真正的叫法是MyBatis拦截器。由于plugin包中还有一个叫Plugin的类,为了避免混淆,在接下来的叙述中,我们用拦截器来指代我们编写的插件类。
拦截器类上有注解Intercepts,Intercepts的参数是Signature注解数组。每个Signature注解都声明了当前拦截器类要拦截的方法。Signature注解中参数的含义如下:
- type:拦截器要拦截的类型。YeecodeInterceptor拦截器要拦截的类型是ResultSetHandler类型。
- method:拦截器要拦截的type类型中的方法。YeecodeInterceptor拦截器要拦截的是ResultSetHandler类型中的handleResultSets方法。
- args:拦截器要拦截的type类型中method方法的参数类型列表。在YeecodeInterceptor拦截器中,ResultSetHandler类型中的handleResultSets方法只有一个Statement类型的参数。
当我们要拦截多个方法时,只需要在Intercepts数组中放入多个Signature注解即可。
Interceptor接口中有三个方法供拦截器类实现,这三个方法的含义解释如下:
- intercept:拦截器类必须实现该方法。拦截器拦截到目标方法时,会将操作转接到该intercept方法上,其中的参数Invocation为拦截到的目标方法。在我们的YeecodeInterceptor拦截器的intercept方法中,会先执行原有的方法并获得原方法的输出结果,然后打印出原方法输出结果的数目,最后返回了原有结果。这样YeecodeInterceptor拦截器便实现了打印结果数目的功能。
- plugin:拦截器类可以选择实现该方法。该方法中可以输出一个对象来替换入参传入的目标对象。在YeecodeInterceptor拦截器中,我们没有实现该方法,而是直接使用了Interceptor接口中的默认实现。在默认实现中,会调用
Plugin.wrap方法给出了一个原有对象的包装对象,然后用该对象来替换原有对象。 - setProperties:拦截器类可以选择实现该方法。该方法用来为拦截器设置属性。在YeecodeInterceptor拦截器中,我们使用该方法为拦截器设置了info属性的值。
拦截器配置结束后,还需要将拦截器设置到MyBatis的配置中才能生效。下面代码给出了YeecodeInterceptor拦截器在配置文件中的配置片段。
<plugin interceptor="com.github.yeecode.mybatisdemo.plugin.YeecodeInterceptor">
<property name="preInfo" value="本次查询记录数目"/>
</plugin>
拦截器配置完成后,重新启动MyBatis就可以使拦截器生效。在配置了YeecodeInterceptor拦截器后,当我们查询列表形式的的结果时,控制台会打印出当前查询结果的数目,如图所示。
该示例的完整代码请参见github中yeecode/MyBatisDemo开源项目中的示例28
这样,我们已经完成了一个简单的MyBatis拦截器的开发、配置、使用工作。
以上内容均参考《通用源码阅读指导书——MyBatis源码详解》一书。
这是一本以MyBatis的源码为实例讲述源码阅读方法的书籍,并且附带有示例项目源码,MyBatis的全中文注解。书籍还总结了大量的编程知识和架构经验,对提升编程和架构能力十分有用。
MyBatis拦截器的开发还是很容易上手的,大家可以在日常使用中根据实际需要为其开发一些拦截器以扩展MyBatis的功能。至于MyBatis拦截器的实现原理,大家可以参考上面介绍的书籍。
可以访问个人知乎阅读更多文章:易哥(https://www.zhihu.com/people/yeecode),欢迎关注。
