MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:
Executor
:(update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
ParameterHandler
:(getParameterObject, setParameters)
ResultSetHandler
:(handleResultSets, handleOutputParameters)
StatementHandler
:(prepare, parameterize, batch, update, query)
通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可。
// ExamplePlugin.java
@Intercepts({
@Signature(
type= Executor.class,
method = "update",
args = {
MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
private Properties properties = new Properties();
public Object intercept(Invocation invocation) throws Throwable {
// implement pre processing if need
Object returnObject = invocation.proceed();
// implement post processing if need
return returnObject;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}
以下配置在springboot中可以直接使用Bean进行配置。
<!-- mybatis-config.xml -->
<plugins>
<plugin interceptor="org.mybatis.example.ExamplePlugin">
<property name="someProperty" value="100"/>
</plugin>
</plugins>
上面的插件将会拦截在 Executor 实例中所有的 “update” 方法调用, 这里的 Executor 是负责执行底层映射语句的内部对象。
解析:
我们先来看@Intercepts
这个注解,只有一个参数,是个数组
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Intercepts {
Signature[] value();
}
@Intercepts({
@Signature(
type= Executor.class,
method = "update",
args = {
MappedStatement.class,Object.class})})
数组中每个元素都为这样一个对象。type的值可以是上述四个阶段,Executor.class
,ParameterHandler.class
,ResultSetHandler.class
,StatementHandler.class
method
即上述定义的方法,也是上述四个阶段类中的方法,args
,则为这些方法的入参。关于四个阶段的具体含义不多解释,见名知意。
那么我们可以使用插件做什么事情呢?
- 1、比如可以做数据库操作审计日志。xxx,什么时间,插入某个条数据,或者修改了某个数据,原数据是什么。
- 2、比如分页。
- 3、比如自动设置一些默认字段。