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

文章目录

一、项目背景

MySQL数据库使用Mybatis查询拼接select语句中进行<if>条件拼接的时候,发现带数字的或者带单个字母的字符串失效问题。

举例说明:我Log对象有个属性accountId是字符串类型,假设我给它赋值为"1",按常理sql拼接的应该是and account_name = 'unmadmin' ,然而实际判断拼接的却是and account_name != 'unmadmin',明显感觉问题出在这里and log.accountId == '1' 这里校验失败了,或者说失效了,估计很多人会踩坑,那么为什么呢?不应该啊?所以此刻就是为了定位它原因。

Log 对象

java 复制代码
public class Log {
    private String logId;
    private String accountId;
    private String accountName;
}

xml

java 复制代码
<select id="queryOperateLog" resultType="Log">
	select * from user 
	<where>
            1 = 1
            <if test="log.accountId != null and log.accountId != '' and log.accountId == '1'">
                and account_name = 'unmadmin'
            </if>
            <if test="log.accountId != null and log.accountId != '' and log.accountId != '1'">
                and account_name != 'unmadmin'
            </if>
   </where>
   order by exectime desc
 </select>         

二、真实错误原因说明

结论: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,具体如下

错误写法:你这么写判断也失效

java 复制代码
<if test="type=='y'">
	and status = 0
</if>

正确写法:

java 复制代码
<if test='type=="y"'>
	and status = 0
</if>

四、参考文献

备注说明:这东西不是我研究出来的,是恰巧搜到了两位道友的博客才有所了解的:↓

道友1博客:mybatis中条件判断带数字的字符串

道友2博客:Mybatis if 判断等于一个字符串

另外我实际追踪过源码,因为我猜测是获取对象值进行类型转换拼接sql的时候出现了判断问题,但是追着追着就跟踪丢了,所以源码究竟哪里进行转换的我也没找到,如果有道友找到了也可以分享出来一起学习下;

另外我甚至翻阅了Mybatis的OGNL表达式,但是也没找出个所以然来,我只知道accountId == '1'确实进行了类型转换,但是究竟是往字符转还是往数字类型转我也不知道,因为找不到官网做论证,所以这块如果有道友真正找到了也可以分享出来一起学习下。

完结、撒花!

相关推荐
captain3766 小时前
MyBatis操作数据库(入门1)
数据库·oracle·mybatis
Vegetable_xu1 天前
Spring Bean 循环依赖:为什么有时能过、有时启动就挂
java·spring·mybatis
m0_639906941 天前
MyBatis 核心体系:核心接口、动态 SQL 原理、插件底层机制
java·sql·mybatis
VX_bysjlw9852 天前
基于协同过滤的美食推荐系统的设计与实现32221-计算机毕设原创(免费领源码+带部署教程)
java·spring boot·redis·mysql·tomcat·maven·mybatis
俊昭喜喜里2 天前
Springboot的Mybatis中的条件构造器
数据库·mybatis
2301_32241428043 天前
基于SSM框架的在线考试管理系统的设计与实现14750-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·redis·mysql·tomcat·maven·mybatis·ssm
毕业设计7035 天前
(免费领源码)SSM董家湾线上点餐系统04682- java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
java·redis·mysql·tomcat·maven·mybatis·ssm
云絮.6 天前
mybatis(二)
java·数据库·mybatis
夕除7 天前
redis--主从还是集群,内存
java·spring·mybatis
驭渊的小故事7 天前
MyBatis-Plus 实战指南:从基础 CRUD 到条件构造器与自定义 SQL(二)
数据库·sql·mybatis