背景:mybatis插件(准确的说应该是around拦截器,因为接口名是interceptor,而且invocation.proceed要自己调用,配置中叫插件)功能非常强大,可以让我们无侵入式的对SQL的执行进行干涉,从SQL语句重写、参数注入、结果集返回等每个主要环节,典型的包括权限控制检查与注入、只读库映射、K/V翻译、动态改写SQL。
MyBatis默认支持对4大对象(Executor,StatementHandler,ParameterHandler,ResultSetHandler)上的方法执行拦截,具体支持的方法为:
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed),主要用于sql重写。
ParameterHandler (getParameterObject, setParameters),用于参数处理。
ResultSetHandler (handleResultSets, handleOutputParameters),用于结果集二次处理。
StatementHandler (prepare, parameterize, batch, update, query),用于jdbc层的控制。
大多数情况下仅在Executor做插件比如SQL重写、结果集脱敏,ResultSetHandler和StatementHandler仅在高级场景中使用,而且某些场景中非常有价值。
四大对象的在sql执行过程中的调用链如下:
1,拦截器接口介绍
Mybatis插件可以用来实现拦截器接口Interceptor,在实现类中拦截对象和方法进行处理。
先看拦截器接口,了解该接口中的每一个方法的作用和用法,代码如下:
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
1,setProperties:这个方法时用来传递插件的参数可以通过参数来改变插件的行为。如何传递?如下:
<plugins>
<plugin interceptor="person.david.ssm.interceptor.CameHumpInterceptor">
<property name="prop1" value="value1"/>
<property name="prop1" value="value1"/>
<property name="prop2" value="value2"/>
</plugin>
</plugins>
2,plugin:这个方法的参数就是拦截器要拦截的对象,该方法会在创建被拦截的接口实现类时被调用。通常实现方法如下:
@Override
public Object plugin(Object target) {
return Plugin.wrap(target,this);
}
3,interceptor:这个方法是Mybatis运行时要执行的拦截方法,该参数invocation可以获得很多有用的信息,通常实现方法如下:
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget();
onject result = invocation.proceed();
return result;
}
2,拦截器签名介绍
除了需要实现拦截器接口外,还需要给实现类配置以下的拦截器注解。
@Intercepts和@Signature这两个注解用来配置拦截器拦截的接口的方法,@Intercepts注解中的属性是一个@Signature(签名)数组,可以在同一个拦截器中同时拦截不同的接口和方法。
以拦截ResultSetHandler接口的handleResultSets方法为例,配置签名如下:
@Intercepts(
@Signature(
type = ResultSetHandler.class,
method = "handleResultSets",
args = {Statement.class})
)
@SuppressWarnings({"unchecked","rawtypes"})
public class ResultSetInterceptor implements Interceptor
@Signature注解包含以下三个属性:
- type:设置拦截的接口,可选值是前面提到的四个接口
- method:设置拦截接口中的方法名,可选值是前面四个接口对应的方法,需要和接口匹配
- args:设置拦截方法的参数类型数组,通过方法名和参数类型可以确定唯一一个方法
3,接口使用介绍