mybatis 中<if>条件判断带数字的字符串失效问题

@[toc]
一、项目背景
MySQL 数据库使用 Mybatis 查询拼接 select 语句中进行<if>条件拼接
的时候,发现带数字的或者带单个字母的字符串失效问题。举例说明:我Log对象
有个属性accountId是字符串类型
,假设我给它赋值为“1”,按常理 sql 拼接的应该是and account_name = 'unmadmin'
,然而实际判断拼接的却是and account_name != 'unmadmin'
,明显感觉问题出在这里and log.accountId == '1'
这里校验失败了,或者说失效了,估计很多人会踩坑,那么为什么呢?不应该啊?所以此刻就是为了定位它原因。
Log 对象
xml
二、真实错误原因说明
结论:mybatis会把纯数字的字符串进行强制转换
,就是大白话讲说碰到 log.accountId == '1'它会把'1'强制抓换成字符格式,而字符串“1” = = 字符'1',比较结果为 false。重点
:Mybatis 是使用的 OGNL 表达式来进行解析的,在 OGNL 的表达式中,'1'会被解析成字符,因为 java 是强类型的,char 和 一个 String 会导致不等。所以 if 标签中的 sql 不会被解析。
那么这时候网友会问了,单引号''
和""双引号
在 mysql 中感觉差不多啊,平常使用也没问题啊,其实主要区别在这里,国内chatGPT给出的答案是:

国外chatGPT给出的答案是:

那么网友会问了,平常我使用的时候输入字符串使用单引号''或者双引号""也没碰到过这个问题啊,其实问题出在String accountId值上:
如果accountId值是多个字符串字母或者字符串和数字的组合
,单引号双引号完全没问题。如果accountId值是纯数字
,比如'1' '211'之类的,就会出现问题。
三、解决方案
既然原因已经找到了,那么如何解决它呢,其实有 2 种方案:
3.1 针对纯数字的字符串值场景
方案 1:外面使用单引号,里面使用双引号
错误写法:

正确写法:

方案 2:使用.toString(),这个方案新颖,估计一般人见都没见过,即单引号保留,但是后面多拼接了个.toString()

3.2 针对单个字符的字符串值场景
别以为只有纯数字有问题,实际单个字符也是有问题的
,假设我有个 String type 字段,我给它判断值传字符 y,具体如下
错误写法:你这么写判断也失效
正确写法:
四、参考文献
备注说明:这东西不是我研究出来的,是恰巧搜到了两位道友的博客才有所了解的:↓
道友 1 博客:mybatis中条件判断带数字的字符串道友 2 博客:Mybatis if 判断等于一个字符串
另外我实际追踪过源码,因为我猜测是获取对象值进行类型转换拼接 sql 的时候出现了判断问题,但是追着追着就跟踪丢了,所以源码究竟哪里进行转换的我也没找到,如果有道友找到了也可以分享出来一起学习下;
另外我甚至翻阅了 Mybatis 的 OGNL 表达式,但是也没找出个所以然来,我只知道accountId == '1'
确实进行了类型转换,但是究竟是往字符转还是往数字类型转我也不知道,因为找不到官网做论证,所以这块如果有道友真正找到了也可以分享出来一起学习下。

完结、撒花!
评论