mybatis拦截器 + 自定义注解

背景:

前两天写过一篇关于:mybatis拦截器 + 自定义注解 + 获取注解的属性 的文章,感觉写得不是很好,有很多事情没有说明清楚
包括:

  • mybatis拦截器的 @Signature 注解的几个参数,type, method, args 分别可以取什么值,
  • type 可以有什么类型,
  • 对应的 type它有什么样的method应该怎样写,
  • 参数又应该怎样获取,
    等等,这些都没有说清楚(当时也是因为不知道)。现在得空来补充说明一下。

在mybatis中可被拦截的类型有四种(按照拦截顺序):

  • Executor:拦截执行器的方法。
  • ParameterHandler:拦截参数的处理。
  • ResultHandler:拦截结果集的处理。
  • StatementHandler:拦截Sql语法构建的处理。

image

每一个可被拦截的类型,也可以通过mybatis 的源码可以看得到。
包括它的参数,也是一一对应的。

比如说:
以下这一段,拦截的类型是 Executor,拦截的方法是 :update, 参数有 MappedStatement 和 Object,

@Intercepts({
        @Signature(type = Executor.class,
                method = "update",
                args = {MappedStatement.class, Object.class}),
})

那怎样知道 这个 Executor 下面有什么方法呢?
去这个 Executor 类定义下看看 mybatis源码-git

image

由此,可知,通过这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,这个方法用在其它地方也是通用的。只要知道类名和方法名,就可以知道它上面的注解了。

posted @ 2022-12-24 09:02  aaacarrot  阅读(1074)  评论(0编辑  收藏  举报