目录
🍸前言
🍻一、背景
🍹二、问题处理
💞️三、处理方法
🍸前言
小伙伴们大家好,很久没有水..不是,写文章了,都收到系统的消息了;我算下时间,上周是单休(没时间),在上周还在放假(没家伙什),再上周...
复工已经有一段时间了,这篇文章就记录下前不久遇到的一个开发问题吧(bushi 又水?)
🍻一、背景
看标题可以得知这个异常的情景在于 mapper 接口中使用重载方法,场景如下:
注:本地项目使用的 mybatis 版本不是很高,不清楚高版本中是否存在该问题
在本地调试新改动的部分时,遇到一个奇怪的问题,就是在 Mapper 接口中有一个方法,是按照条件查询指定数据数量的,有一定的概率会出现异常,打印执行的 sql 日志后,发现导致异常的 sql 并不是改动的那部分,不清楚哪里来的 ;另外,此异常不是百分百出现的,有几次重启后是正常的,这就很离谱,埋头研究了半天,放弃了 开始寻找同事帮助,,对话基本如下:
I:"遇到个问题,很奇怪,帮忙瞅瞅,出现的场景是..."
I:"玄学?我不信,发我来瞅瞅"
"6 还真是,清下缓存呢,wtf,会不会是自动优化查询导致的...不应该吧"
”这怎么还有个一样命名的方法(警惕)“
I: 破案了!
一顿操作下来,总算是定位到了异常 sql 的来源了,是该 mapper 接口下的另一个同样名称的重载方法,参数不同,数量也不同;但调用的的确是这个冒牌货
🍹二、问题处理
通过网上查询此类型异常,发现有很多帖子,看了一两个之后,可以确定出现的场景基本都一致,就是程序运行中遇到这种 mapper 中重载方法时,定位到错误的方法,导致数据异常或者说程序报错,类似于这种代码场景,代码中指定的是第二个 方法,但是实际运行时程序执行的是第一个方法,导致异常):
public interface UserMapper {@Select("SELECT * FROM user WHERE id = #{id}")User selectUser(int id);@Select("SELECT * FROM user WHERE name = #{name} AND age = #{age}")User selectUser(String name, int age);
}
具体为什么会遇到这种原因,看到了些参考:
MyBatis通过动态代理实现Mapper接口,生成代理类时可能无法正确处理重载方法,因为代理类需要根据类型和方法名来确定调用哪个方法,忽略掉了参数差异
可以看下这位博主的分析,很详细,定位到了关键代码:
Mybatis和方法重载只能二选一?_mybatis 方法重载-CSDN博客
这也验证了,该异常不是百分百复现,而是概率性闪现,因为启动项目的时候,这两个重载的方法谁会覆盖谁不确定
💞️三、处理方法
既然重载有一定概率导致异常,那么不使用重载便是,可以根据此次业务的需求来命名方法,或者根据该方法的参数来命名方法,尽量减少重复命名
文章到这里就结束了~