mybatis拦截器 + 自定义注解
背景:
前两天写过一篇关于:mybatis拦截器 + 自定义注解 + 获取注解的属性 的文章,感觉写得不是很好,有很多事情没有说明清楚
包括:
- mybatis拦截器的 @Signature 注解的几个参数,type, method, args 分别可以取什么值,
- type 可以有什么类型,
- 对应的 type它有什么样的method应该怎样写,
- 参数又应该怎样获取,
等等,这些都没有说清楚(当时也是因为不知道)。现在得空来补充说明一下。
在mybatis中可被拦截的类型有四种(按照拦截顺序):
- Executor:拦截执行器的方法。
- ParameterHandler:拦截参数的处理。
- ResultHandler:拦截结果集的处理。
- StatementHandler:拦截Sql语法构建的处理。
每一个可被拦截的类型,也可以通过mybatis 的源码可以看得到。
包括它的参数,也是一一对应的。
比如说:
以下这一段,拦截的类型是 Executor,拦截的方法是 :update, 参数有 MappedStatement 和 Object,
@Intercepts({
@Signature(type = Executor.class,
method = "update",
args = {MappedStatement.class, Object.class}),
})
那怎样知道 这个 Executor 下面有什么方法呢?
去这个 Executor 类定义下看看 mybatis源码-git
由此,可知,通过这4种拦截类型,它下面的方法,方法下面的参数,我们都可以找得到了。
它的参数的位置也是对应的,所以比如这个 update 方法,它第一个参数是 MappedStatement,第二个参数就是 Object,就是要 update 的真正对象。
那如果要获取到这个对象的值,通过
Object obj = invocation.getArgs()[1];
就可以直接拿得到了。类型,也是一致的。
获取mapper方法上的注解
这几天一直在看这个东西,在上一篇文章中还很专注地描述了怎样获取 mapper方法上的注解怎样获取,
其实只有能拿得到这个 MappedStatement就可以了,
做法如下:
MappedStatement mappedStatement = (MappedStatement)invocation.getArgs()[0];
SM4MACFieldAnnotation annotation = null;
try {
String id = mappedStatement.getId();
String className = id.substring(0, id.lastIndexOf("."));
String methodName = id.substring(id.lastIndexOf(".") + 1);
final Method[] method = Class.forName(className).getMethods();
for (Method me : method) {
if (me.getName().equals(methodName) && me.isAnnotationPresent(SM4MACFieldAnnotation.class)) {
return me.getAnnotation(SM4MACFieldAnnotation.class);
}
}
} catch (Exception ex) {
log.error("", ex);
}
return annotation;
emmm, 其实只要拿得到 className, methodName 就好了。。。
final Method[] method = Class.forName(className).getMethods();
for (Method me : method) {
if (me.getName().equals(methodName) && me.isAnnotationPresent(SM4MACFieldAnnotation.class)) {
return me.getAnnotation(SM4MACFieldAnnotation.class);
}
}
emmm,这个方法用在其它地方也是通用的。只要知道类名和方法名,就可以知道它上面的注解了。