该系列文章针对 Mybatis 3.5.1 版本

在 mybatis 中允许针对 SQL 在执行前后进行扩展操作,而这些扩展操作也叫做插件。

在 Mybaits 中允许用插件来拦截的方法包括:

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

通过插件可以实现 SQL 打印,分页插件等功能。

这时候就会延伸出一个问题:如果存在多个插件,这些插件的执行顺序是怎样的?

一、插件的执行顺序

插件执行顺序一共有两种

1、不同拦截对象的执行顺序

Mybatis 提供了对如下四种对象的拦截,分别是:ExecutorParameterHandlerResultSetHandlerStatementHandler。针对这四种对象的拦截的执行顺序是固定的,因为 Mybatis 代码的执行流程是固定的。

SimpleExecutor#query 来说,这四种对象的执行代码如下:

如下述代码:

通过源码知道,执行顺序为:Executor` -> `StatementHandler` -> `ParameterHandler` -> `StatementHandler` -> `ResultSetHandler

虽然中间 StatementHandler 执行了多次,但是总的来说,执行顺序优先级从高到低为:Executor` -> `StatementHandler` -> `ParameterHandler` -> `ResultSetHandler

2、同种拦截对象的执行顺序

针对同种对象如果存在多种拦截器对象,其拦截顺序如何?

首先在前面的文章中,知道了插件功能的实现是通过代理的方式对原有的如:ExecutorParameterHandler 等进行了代理增强,而经过代理后的原有的 ExecutorParameterHandler 等对象会以如下方式存在:

如图,存在多个拦截器都是先进后出,针对代理模式来说来说,可以对被代理的原始对象的处理前后进行代码增强操作。

而那个拦截器优先执行,取决于在生成代理对象时的顺序,也就是包裹在最外层的插件(拦截器)优先执行。

来回顾一下代理对象生成时的逻辑然后结合mybatis-config.xml 配置文件的关于 <plugins> 的配置信息,即可知道相关的执行顺序。

来看代理生成代码InterceptorChain#pluginAll,如下:

如上述代码所示,通过遍历 interceptors List 列表对 target 对象进行包装(target 可以是 Executor or ParameterHandler等)。

也就是在 List 列表的最开始的 interceptor 插件最先被包裹在 target 对象外层,也就是如下图所示:

如图,同个目标对象的多个拦截器的执行顺序,取决于mybatis 加载配置后,拦截器在 List<Interceptor> interceptors 中的顺序。

再来回顾一下 <plugins> 解析的关键代码,如下:

如上图所示,在配置文件中越靠前的插件配置,在 interceptors List 列表中的位置自然越靠前,其执行顺序自然越靠后。

总结:同个对象的多个拦截器执行顺序根据配置文件 mybatis-config.xml 插件配置顺序有关,配置越靠前,执行顺序越靠后

二、通过代码验证插件执行顺序

2.1、验证不同对象拦截器的执行顺序

验证入口为 Executor#query ,准备查询接口,同时准备4个插件拦截器,并将四个插件拦截器配置到 mybatis-config.xml 配置文件 <plugins> 标签中(顺序无所谓)

2.1.1、查询接口忽略

2.1.2、四个插件拦截器

如上述定义了四个插件拦截器,分别对应四种对象的拦截器,以 Executor 拦截器为例 ,代码如下:

通过打印日志,查看执行顺序,其他拦截器相同

2.1.3、在配置文件中配置

如上述配置,为了验证配置顺序无关性,特地打乱其配置顺序。

2.1.4、执行结果

执行结果正如我们所预料的一样,执行顺序Mybatis 已经固化了。

2.2、验证多个同对象拦截器的执行顺序

Executor#query 为例

2.2.1、创建多个 Executor 拦截器,并拦截同一个方法 Executor#query

其中ExecutorQueryPlugin1代码如下:

2.2.2、配置文件配置

如上述配置所示,拦截器配置顺序为 2,1,3,通过上述结论可以得出,其执行顺序为:3,1,2----2,1,3

2.2.3、测试结果

控制台打印信息如下:

三、总结

Mybatis 插件的执行顺序有两种

1、不同拦截对象执行顺序,如下:

Executor` -> `StatementHandler` -> `ParameterHandler` -> `ResultSetHandler

2、拦截相同对象执行顺序,取决于 mybatis-config.xml 中 <plugin> 配置顺序,越靠后,优先级越高。

mybatis plugins_[Mybatis]-[基础支持层]-插件-多个插件执行顺序相关推荐

  1. MyBatis 架构分层与模块划分-基础支持层

    最后一个就是基础支持层.基础支持层主要是一些抽取出来的通用的功能(实现复用),用来支持核心处理层的功能.比如数据源.缓存.日志.xml 解析.反射.IO.事务等等这些功能. 这个就是MyBatis 的 ...

  2. mybatis plugins_[Mybatis]-[基础支持层]-插件-plugin标签解析

    该系列文章针对 Mybatis 3.5.1 版本 一.Mybatis 插件的作用 Mybatis 针对 SQL 映射语句执行过程中进行拦截处理,而对应的拦截器 Mybaits 又称之为 插件(这些插件 ...

  3. mysql基础10(SQL逻辑查询语句执行顺序)

    SQL语句定义顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOIN <rig ...

  4. idea打印sql的插件_[Mybatis]-[基础支持层]-插件-自定义简易SQL打印插件

    该系列文章针对 Mybatis 3.5.1 版本 在 mybatis 中允许针对 SQL 在执行前后进行扩展操作,而这些扩展操作也叫做插件. 在 Mybaits 中允许用插件来拦截的方法包括: Exe ...

  5. sql server解析xml属性为表格_[Mybatis][基础支持层]mapper xml sql 解析

    该系列文章针对 Mybatis 3.5.1 版本 Mybatis 中 标签解析,主要是为了得到两大部分数据 1.Mapper.class 接口 2.SQL 执行语句,结果集映射关系等数据 在上一章中提 ...

  6. 2 数据源配置_[Mybatis]-[基础支持层]-数据源信息-数据源详解

    该系列文章针对 Mybatis 3.5.1 版本 在上一篇文章中,谈到了 <environment> 标签解析会构建 Environment 对象,Environment 对象中有两个关键 ...

  7. mybatis plugins_[MyBatis] SpringBoot 整合Mybatis

    现在基本上搭建一个简单的工程都是三剑客 springboot+mybatis+redis 之前整合Mybatis 都是按照SSM来,所以,这一次带来SpringBoot+MyBatis 的快速整合 p ...

  8. mybatis和spring jdbc持久层框架事务支持分析

    mybatis和spring jdbc持久层框架事务支持分析 ​ 持久层框架中的事务支持指的是持久层框架如何支持数据库事务,我们先梳理出原生数据库事务操作的主线脉络,它是通过java.sql 包下的C ...

  9. Springboot 系列(十二)使用 Mybatis 集成 pagehelper 分页插件和 mapper 插件

    前言 在 Springboot 系列文章第十一篇里(使用 Mybatis(自动生成插件) 访问数据库),实验了 Springboot 结合 Mybatis 以及 Mybatis-generator 生 ...

  10. SpringBoot 2.x 整合Mybatis一:基础

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/80694228 本文出自[赵彦军的博客] 什么是 MyBatis ? MyBatis ...

最新文章

  1. php原生开发规范,php开发规范
  2. C++程序崩溃生成dump
  3. 按一行一行的方法将一个文本文件复制到另一个文件中_大文件上的结构化数据计算示例...
  4. jQuery 参考手册 - 事件
  5. 乐视android版本点四下,EUI5.9+Android7.0刷机包
  6. 使用ExposedObject对Asp.net MVC中匿名类型的JsonResult做单元测试
  7. DevExpress XtraGrid网格控件示例四:初始化新建行的单元格
  8. jquery 动态添加,降低input表单的方法
  9. 设计模式---模板模式(C++实现)
  10. 普通循环和numpy速率对比
  11. SPSS教程—实现多层感知器神经网络
  12. excel输入身份证号码变指数 及自动变数值如何解决?
  13. 截部分陈宏对用线段树解矩形并的轮廓(picture 问题的深入讨论)
  14. 访问网络计算机运行里输入IP,WINDOWS在运行里输入IP地址不能访问网络位置
  15. 支付宝免签,个人支付宝,自动转账,自动提现到银行卡,自动银行卡转账
  16. 扫地机器人腿是咕噜_智能家居 篇一:洒哇地咔钟点狗智能擦地机初步评测:试水之作 略有失望...
  17. 【CSS—美化网页元素】
  18. 中国家庭收入调查数据(CHIP)
  19. SQL数据库“正在恢复”,解决和查看方法
  20. 杰理之手持式频谱分析仪设置【篇】

热门文章

  1. 九度 题目1183:守形数----------------我用的方法自创
  2. Ajax关于readyState和status的讨论
  3. Longhorn的糟糕体验!
  4. linux tomcat reload,linux-tomcat安装配置
  5. 基于node.js的express使用数据库时,解决异步调用的问题
  6. QoS中流量监管和流量整形详解
  7. NYOJ--448--寻找最大数
  8. webpack 优化react项目没有解决的问题
  9. JavaScript (十九):DOM对象其它操作
  10. linux下的系统服务管理及日志管理