tamako tamako
首页
  • Mysql
  • Redis
  • JVM
  • 个人开源项目 (opens new window)
  • 开源官网 (opens new window)
  • B站主页 (opens new window)
  • 摄影
  • 网站
  • 资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

tamako | 玉子

胜人者有力,自胜者强
首页
  • Mysql
  • Redis
  • JVM
  • 个人开源项目 (opens new window)
  • 开源官网 (opens new window)
  • B站主页 (opens new window)
  • 摄影
  • 网站
  • 资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Mybtais插件开发

    • 工作流程
      • 执行流程
      pruedream
      2023-12-11
      Mybatis
      目录

      Mybtais插件开发

      # Mybtais插件开发

      mybatis拦截器可以对下面4种对象进行拦截:

      1、Executor:mybatis的内部执行器,作为调度核心负责调用StatementHandler操作数据库,并把结果集通过ResultSetHandler进行自动映射

      2、StatementHandler: 封装了JDBC Statement操作,是sql语法的构建器,负责和数据库进行交互执行sql语句

      3、ParameterHandler:作为处理sql参数设置的对象,主要实现读取参数和对PreparedStatement的参数进行赋值

      4、ResultSetHandler:处理Statement执行完成后返回结果集的接口对象,mybatis通过它把ResultSet集合映射成实体对象

      拦截的原理是动态代理



      # 工作流程

      在mybatis中提供了一个Interceptor接口,通过实现该接口就能够自定义拦截器,接口中定义了3个方法:

      public interface Interceptor {
        Object intercept(Invocation invocation) throws Throwable;
        default Object plugin(Object target) {
          return Plugin.wrap(target, this);
        }
        default void setProperties(Properties properties) {
          // NOP
        }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      • intercept:在拦截目标对象的方法时,实际执行的增强逻辑,我们一般在该方法中实现自定义逻辑
      • plugin:用于返回原生目标对象或它的代理对象,当返回的是代理对象的时候,会调用intercept方法
      • setProperties:可以用于读取配置文件中通过property标签配置的一些属性,设置一些属性变量

      看一下plugin方法中的wrap方法源码:

      public static Object wrap(Object target, Interceptor interceptor) {
        Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
        Class<?> type = target.getClass();
        Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
        if (interfaces.length > 0) {
          return Proxy.newProxyInstance(
              type.getClassLoader(),
              interfaces,
              new Plugin(target, interceptor, signatureMap)); //Plugin 类实现了InvocationHandler,在其重写的invoke方法也就是 代理对象执行的方法中 调用了我们之前重写的intercept方法
        }
        return target;
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      // Plugin 类重写的 方法invoke
      
      @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
          try {
            Set<Method> methods = signatureMap.get(method.getDeclaringClass());
            if (methods != null && methods.contains(method)) {
                // 我们自己重写的intercept方法的内容
              return interceptor.intercept(new Invocation(target, method, args));
            }
            return method.invoke(target, args);
          } catch (Exception e) {
            throw ExceptionUtil.unwrapThrowable(e);
          }
        }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15

      可以看到,在wrap方法中,通过使用jdk动态代理的方式,生成了目标对象的代理对象,在执行实际方法前,先执行代理对象中的逻辑,来实现的逻辑增强 在实际执行前会执行拦截器中的intercept方法:



      # 执行流程

      1. Executor发起sql执行任务

      2. 先调用statementHandler中的prepare()进行SQL的编译

      3. 然后调用statementHandler中的parameterize()设置参数。 这里其实真正设置参数的是ParameterHandler中的setparameters()方法,该方法与typeHandler进行参数类型的转换。

      4. 然后执行query/update方法,这里使用ResultSetHandler进行结果的组装工作

        参考 https://blog.51cto.com/c959c/5326665

      在mybatis中,不同类型的拦截器按照下面的顺序执行:

      Executor -> StatementHandler -> ParameterHandler -> ResultSetHandler
      
      1

      以执行query 方法为例对流程进行梳理,整体流程如下:

      1、Executor执行query()方法,创建一个StatementHandler对象

      2、StatementHandler 调用ParameterHandler对象的setParameters()方法

      3、StatementHandler 调用 Statement对象的execute()方法

      4、StatementHandler 调用ResultSetHandler对象的handleResultSets()方法,返回最终结果

      参考https://mdnice.com/writing/135d7356e3a44476ac7d86f61d2d210e

      #Mybatis
      上次更新: 2024/08/09, 16:07:34
      最近更新
      01
      骄惰怯
      08-10
      02
      谦虚谦虚谦虚
      08-09
      03
      长期主义
      07-17
      更多文章>
      Theme by Vdoing | Copyright © 2019-2024 tamako | MIT License
      • 跟随系统
      • 浅色模式
      • 深色模式
      • 阅读模式