上周遇到了一个需求:考虑到用户信息的安全性,用户的手机号统一在用户中心进行存储,我们业务库中的客户手机号需要进行清除,新增和修改数据都不能涉及到手机号,然后提供查询的接口需要手机号信息就通过用户id到用户中心那边查询。
由于涉及到的表比较多,然后提供的接口也比较多,就想到了通过mybatis插件的方式来处理。
使用
1、实现Intercept接口中的方法
public interface Interceptor {
// 执行拦截逻辑的方法
Object intercept(Invocation invocation) throws Throwable;
// 决定是否触发intercept()方法
default Object plugin(Object target) {
return Plugin.wrap(target, this);
}
// 根据配置初始化Interceptor对象
default void setProperties(Properties properties) {
// NOP
}
}
2、在类上加@Intercepts、@Signature注解
@Signature注解标识了该插件需要拦截的方法信息。即一个方法签名,包括类名.方法名(参数列表),可以确定一个唯一的方法。
具体可拦截的方法如下:
- Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
- ParameterHandler (getParameterObject, setParameters)
- ResultSetHandler (handleResultSets, handleOutputParameters)
- StatementHandler (prepare, parameterize, batch, update, query)
@Signature属性
- type:指定需要拦截的类型,即上述的Executor、ParameterHandler、ResultSetHandler 、StatementHandler四种类型。
- method:指定需要拦截的方法。即上述括号中的方法。
- args:指定拦截方法的参数列表。
@Intercepts(@Signature(type = Executor.class, method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))
public class TestInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 写拦截的逻辑
return null;
}
}
3、将该插件加入到spring容器中进行管理
直接在类上加上@Component即可。
4、拦截方法的时机
即拦截每个方法都能处理什么事情。这样我们就可以知道我们的需求需要拦截哪个(哪些)方法进行实现。
TODO
小结
mybatis插件功能很强大,可以重写已有方法的行为,但影响的范围也非常广,使用插件要慎之又慎。
拦截方法的时机这个需要深入去看mybatis各个模块的运作原理。这个后面研究mybatis源码时再进行扩充。