最近项目用上了mybatis, 但是想像hibernate那样能打印sql, 于是写了个基于mybatis拦截器的sql打印, 参考这个https://blog.22xcode.com/post/78

然后, 碰到了问题, 拦截器会重复输出一句sql

mybatis sql: SELECT id, name FROM usermybatis sql: SELECT id, name FROM user

排查下, 项目里跟mybatis有关的就只有pagehelper了, 猜测可能是pagehelper 为了分页再发了一条算总数count的sql, 而打印sql的拦截器没有获取到count查询的完整sql, 所以看上去发了两遍一样的sql

网上找了下拦截器的资料, 发现基本都是这个样子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Th2xecl-1656070640683)(/storage/thumbnails/_signature/3PUPLE2S14QE5OG0JJL7RED3FL.png)]

大概意思就是后定义/加载的拦截器会先执行.

于是更改配置, 将sql打印拦截器在pagehelper的拦截器之后执行

 @Autowiredprivate List<SqlSessionFactory> sqlSessionFactoryList;/*** 在分页拦截器后加载*/@AutowiredPageHelperAutoConfiguration pageHelperAutoConfiguration;@PostConstructpublic void registerInterceptor() {if (enableSqlLog) {MybatisSqlLogInterceptor interceptor = new MybatisSqlLogInterceptor();for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {Configuration configuration = sqlSessionFactory.getConfiguration();if (!containsInterceptor(configuration, interceptor)) {configuration.addInterceptor(interceptor);}}log.warn("[mybatis sql log]已启用, 请检查当前是否为开发环境");} else {log.info("[mybatis sql log]已禁用");}}

其实也试了下@AutoConfigureAfter, 但是发现不起作用, 后续再琢磨下吧.

配置完成, 再次执行查询, sql只打印一次, 说明sql打印拦截器在分页拦截器之前被调用, 完成

但是为什么先加载的拦截器反而后执行, 网上好像没啥资料, 那就只能自己翻翻源码了.

debug看了下, 找到了这个类

package org.apache.ibatis.plugin;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class InterceptorChain {private final List<Interceptor> interceptors = new ArrayList<>();public Object pluginAll(Object target) {for (Interceptor interceptor : interceptors) {target = interceptor.plugin(target);}return target;}public void addInterceptor(Interceptor interceptor) {interceptors.add(interceptor);}public List<Interceptor> getInterceptors() {return Collections.unmodifiableList(interceptors);}}

InterceptorChain顾名思义, 拦截链, 可以看到项目定义的拦截器都在InterceptorChain内用ArrayList存储起来

核心是这个InterceptorChain#pluginAll这个方法

解析下

pluginAll方法中, 遍历interceptors, 为目标对象创建代理.

即, 在这一步, 先加载的拦截器会优先被遍历, 会优先对目标对象进行代理,

后加载的拦截器, 在原有的代理之上再进行代理, 一层包一层, 类似洋葱.

当方法被调用时, 会先执行最外层的代理方法.

所以, 先加载到的拦截器, 反而是最后执行.

MyBatis拦截器执行顺序相关推荐

  1. 拦截器原理多个拦截器执行顺序

    拦截器原理多个拦截器执行顺序 1.根据当前请求,找到**HandlerExecutionChain[可以处理请求的handler以及handler的所有 拦截器] 2.先来顺序执行 所有拦截器的 pr ...

  2. java 拦截器顺序_Springmvc拦截器执行顺序及各方法作用详解

    实现HandlerInterceptor接口或者继承HandlerInterceptor的子类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInt ...

  3. Mybatis 拦截器执行原理分析

    目录 1.拦截器执行流程 2.拦截器实现原理 3.拦截器用法 1.mybatis拦截器实现原理 2.拦截器实现原理 在Mybaits中 拦截器需实现Interceptor接口,加上如下注解 @Inte ...

  4. 犯罪心理解读Mybatis拦截器

    原文链接:"犯罪心理"解读Mybatis拦截器 Mybatis拦截器执行过程解析 文章写过之后,我觉得 "Mybatis 拦截器案件"背后一定还隐藏着某种设计动 ...

  5. 关于Mybatis拦截器的使用

    关于Mybatis拦截器的使用 1 Mybatis拦截器的使用 1 自定义拦截器 1 Interceptor接口 2 @Intercepts注解 3 @Signature注解 2 注册拦截器 3 拦截 ...

  6. 面试官:你能说说MyBatis拦截器原理吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:Format cnblogs.com/fangjian042 ...

  7. MyBatis拦截器原理探究MyBatis拦截器原理探究

    MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis拦截 ...

  8. MyBatis拦截器有哪些以及分析

    MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允许你在已映射语句执行过程中 ...

  9. MyBatis拦截器原理探究

    MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允 ...

  10. insert into select 主键自增_springboot2结合mybatis拦截器实现主键自动生成

    点击上方蓝字关注我们 1 01 前言 前阵子和朋友聊天,他说他们项目有个需求,要实现主键自动生成,不想每次新增的时候,都手动设置主键.于是我就问他,那你们数据库表设置主键自动递增不就得了.他的回答是他 ...

最新文章

  1. 在Yolov5 Yolov4 Yolov3 TensorRT 实现Implementation
  2. 用FTP客户端实现主机和虚拟机之间文件的传输(方法2)
  3. mysql 优化 类型_MySQL数据类型的优化选择
  4. AT91RM9200Linux移植笔记(三)-移植Linux kernel 2.6.17
  5. 分析工作试用期收获_免费使用零编码技能探索数据分析
  6. android outofmemory 原理及解决方案
  7. netlify 部署vue_如何使用Netlify构建和部署网站-全面的教程
  8. 为什么有的电路中要有两单片机
  9. shouldoverrideurlloading为什么有时候不走_为什么付出越多,对方就越不懂得感恩,婚姻有时候也需要斤斤计较...
  10. hibernate could not resolve property
  11. systen v消息队列(一)
  12. cad化气路图_气路图符号cad下载
  13. 抢红包案例分析以及代码实现(一) 侵立删
  14. oracle 同比增长率计算
  15. css实现方框内打勾
  16. 财务管理系统-数据库模块
  17. 当你对未来迷茫的时候,请打开这个锦囊
  18. 开心网外挂开发之 三
  19. php实现拼音转中文,PHP将中文转换成拼音的方法
  20. 如何发布自己的npm包(超详细步骤,博主都在用)

热门文章

  1. Windows 7 专业版如何安装英文、中文语言包
  2. js对象写入键值对_js对象添加键值对
  3. 捷联式惯导系统初始对准
  4. 美国经济数据向淡带来重压 美元指数受阻于7月高点?
  5. web前端教程,详解引入CSS的4种方式
  6. jeesit1.27使用(2)-图片处理
  7. 制定自动化测试实施计划
  8. 9008刷机教程oppo_OPPO手机解锁教程
  9. 关于ATmega328P和ATmega328PB中16位定时器的使用
  10. mtk2503 如何支持使用epo?