MyBatis Bug 记录

发布时间 2023-07-16 10:25:36作者: ivanohohoh

动态SQL

If 参数

Mybatis if 判断 Integer 类型的值不等于 '' 引发的问题(!='' 等价于 !=0)
csdn-ref

结论

对于 Number 类型参数,age != '' 被 Mybatis 认定为 age != 0

解决方案

  1. ✅ 使用 1,2 来表示数据含义
  2. ✅ 添加 or age == 0,来规避该问题
  3. ✅ 修改字段类型为 varchar
  4. 不使用 Number 类型,改用基本类型,但是基本类型存在数据允许为 null 时可能导致的异常

问题分析

黑盒分析

把底层原因看作黑盒,先不考虑 mybatis 源码等问题,先通过语法,参数排查掉外因,再通过判断找到问题的表象。

比如这个问题的表象就是If test 语句中,Number 类型参数为 0 时, 无法正确通过 test = "age != null & age != ''" 的判断。

采用解决方案 2, 通过逻辑来规避该问题

白盒分析

如果有必要,才进一步挖掘问题的原因,往往会受益。

比如导致该问题的原因是 OGNL 表达式,在判断 xx != '' 时,会执行 xx != ''.toString().length 操作,那么你就可以规避在那些所有使用 OGNL 库的框架中出现类似的问题。

常见异常

SqlSession was not registered for......

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4ad37127] was not registered for synchronization because synchronization is not active
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@68085783] will not be managed by Spring
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4ad37127]

大部分情况下 sql 语句直接使用了值为 null 的参数后,就会打印以上信息。