当前位置: 首页 > news >正文

MyBatis-Plus拦截器接口InnerInterceptor失效?因MyBatis缓存机制而踩的一个深坑

InnerInterceptor 接口是 MyBatis-Plus 提供的一个拦截器接口,用于实现一些常用的 SQL 处理逻辑。例如某个组件运作在多系统的平台上,不同系统需要隔离,于是可以通过这个拦截器接口,给每一条要执行的sql末尾拼接一个AND systemId = "?"的条件来实现不同系统只能查到对应系统ID的数据。

具体玩法样例可以参考这个文章:

Mybatis-Plus实现拦截器接口InnerInterceptor

而今天项目遇到的一个bug情景如下:
所有的sql原本都要通过拦截器拼接这个校验系统ID的条件,但其中一条sql因为要查整个数据库中的数据是否有重复,所以就要去掉这个拼接的条件进而查询整个库表。这里我们之前已经有代码可以实现了,简单来说就是在拦截器里加个if,只有在满足if条件后才去拼接条件sql。
然而复制了之前能跳过拦截器的方法去开发这次的新需求,却非常意外的没能生效,sql语句还是把校验systemId的条件给拼接进去了。打了断点也摸不着头脑,明明代码是一模一样的呀,接收到的参数也是满足跳过拦截条件的,为什么还是会被拦截了呢?

在这里插入图片描述

其实标题已经算剧透了,大伙心里应该都有数了吧?那就来详细说说找出问题的步骤:


先是把断点打到了selectOne前后,发现日志没打印sql,然而依然获取到了查询结果的对象,这是怎么一回事?

继而把断点打到拦截器里,发现在执行这条mybatis-plus的方法时根本就没进拦截器,断点没捕获到。

此时就有很多种猜测了,甚至还猜想过会不会和service层加了事务有关

不过最终的正解是由于mybatis的缓存机制,因为我在该方法里执行这条查询sql前已经执行过一遍相同的sql了(目的是先查询一遍加了systemId校验的,再查一遍全表的),所以mybatis的缓存机制生效,直接将已缓存的sql包括结果直接返回了,所以压根就没执行这条想查全表的sql,故而别说拦截器里的if是否判断了,就连进都没进来,这就是拦截器里断点没捕获到的原因。


解决方法:

1、配置文件中加上
# propertiesmybatis.configuration.local-cache-scope=statement
# yamlmybatis:configuration:local-cache-scope: statement

关闭mybatis的一级缓存

ps:金融行业不适合使用这个一级缓存,容易出现数据不一致,也没提升多少性能

2、在不能关闭一级缓存的情况下,重新写一条结果一样但内容不一样的sql

sql有差别就不会走缓存机制了。比如你之前的sql是用mybatis生成的,这里就直接用Mapper手写一条


THX!


http://www.mrgr.cn/news/21073.html

相关文章:

  • AES加密算法说明
  • 【C题成品论文2已出】24数学建模国赛C题第二套成品论文(附参考代码)免费分享
  • Arcgis字段计算器:随机生成规定范围内的数字
  • PS插件DR5白金版下载安装教程磨皮美颜一键调色磨皮美白皮肤百度网盘分享链接地址
  • 【开端】服务器间免密登录配置
  • 乘法问题c++
  • 【OpenCV1】虚拟环境的使用、opencv的使用、图像和视频的创建和显示
  • 搭建 canal 监控mysql数据到Elasticsearch(总结)
  • 20240907 每日AI必读资讯
  • 关于 export HF_ENDPOINT=https://hf-mirror.com
  • CMU 10423 Generative AI:lec3(阅读材料:GPT1论文解读)
  • 【代码随想录|贪心part04以后——重叠区间】
  • 「账号诊断」上线,「违规检测」全新改版!企业运营效率再提升!
  • AI模型:追求全能还是专精?-- 之6 语言复杂度类别(Category 0~3 类)和语言功能性类型(Type 0~Ⅲ 型)之1
  • 【电机控制】TC275芯片——ADC外设驱动的配置与实现
  • vivado 添加多循环路径
  • 挑战亿级数据:安企CMS性能优化的探索之路
  • PE193
  • Alternative account/备选科目代码配置说明 【1:1和国家科目配置运营科目】
  • plot()画图,横或纵坐标出现乱序