mybatis的if判断==‘1‘不生效,改成‘1‘.toString()才生效的原因

mybatis的xml文件中的if判断=='1'不生效,改成'1'.toString()才生效

Mapper接口传入的参数

java 复制代码
    List<Table> queryList(@Param("state") String state);

xml内容

xml 复制代码
<where>
	<if test="state != null and state == '1'">
		AND EXISTS(select 1 from t_space.base_outlay where outlay_card_no = t1.outlay_card_no)
    </if>
    AND EXISTS(select 2 from t_space.base_outlay where outlay_card_no = t1.outlay_card_no)
</where>

select 1的sql一直没进到,能确定state就是1,改成<if test="state != null and state == '1'">或者<if test='state != null and state == "1">问题成功解决,网上大量博客未说明原因,如:参考1|参考2

多次询问ai给出如下原因有点说服力:

总结的就是:

在 MyBatis 的 OGNL 或 SpEL 表达式引擎中,写法 == '1' 中的 '1' 被解析为 Character 类型(char),而不是字符串!

而你传入的参数 state是 String 类型,所以比较时会出现 类型不一致导致判断失败:

String("1") == Character('1') ❌ 不成立

以下是灵码给的原因:

复制代码
明白了,你发现:

<if test="state != null and state == '1'"> ❌ 不生效
<if test="state != null and state == '1'.toString()"> ✅ 生效了
这说明你在 MyBatis 的 EL 表达式中遇到了类型匹配问题。我们来深入分析原因。

🧪 问题本质:'1' 和 '1'.toString() 在 MyBatis EL 中的类型不同
在 Java 中:

java
'1'        // 是 char 类型(注意是单引号)
"1"        // 是 String 类型(双引号)
"1".toString() == "1"  // 成立
但在 MyBatis 的 OGNL 或 SpEL 表达式引擎中,写法 == '1' 中的 '1' 被解析为 Character 类型(char),而不是字符串!

而你传入的参数 state 是 String 类型,所以比较时会出现 类型不一致导致判断失败:

java
String("1") == Character('1') ❌ 不成立
当你写成:

xml
state == '1'.toString()
此时 '1'.toString() 返回的是字符串 "1",两边就都是 String 类型了,比较就能成功。

✅ 正确写法推荐
为了避免这种陷阱,建议统一使用双引号表示字符串:

xml
<if test="state != null and state == '1'">
应该改为:

xml
<if test="state != null and state == '1'.toString()">
或者更清晰地写成:

xml
<if test="state != null and state == '1'.toString().intern()">
但最推荐的是:

xml
<if test="state != null and outlayAddAble.equals('1')">
⚠️ 注意:在 MyBatis 的表达式中,使用 .equals() 比 == 更安全,因为 == 判断的是引用地址,.equals() 才是值比较。

✅ 最佳实践总结
写法	是否推荐	原因
state == '1'	❌ 不推荐	'1' 是 char 类型,和 String 不匹配
state == '1'.toString()	✅ 推荐	强制转成 String 类型比较
outlayAddAble.equals('1')	✅✅ 强烈推荐	使用 .equals() 进行值比较,语义正确
outlayAddAble.toString() == '1'	⚠️ 避免	== 是引用比较,容易出错
outlayAddAble.toString().equals('1')	✅ 推荐	安全通用
✅ 推荐最终写法
xml
<if test="state != null and outlayAddAble.equals('1')">
    AND EXISTS(select 1 from t_space.base_outlay where outlay_card_no = t1.outlay_card_no)
</if>
这样可以确保:

参数是字符串;
比较是值比较;
不受底层表达式引擎对 '1' 解析为 char 的影响。
如果你还有疑问或需要进一步验证,可以把生成的 SQL 日志贴出来一起分析。
相关推荐
用户3126874877207 小时前
线程池到底怎么管理线程的?从 ThreadPoolExecutor 到拒绝策略全链路拆解
java
cpolar技术支持7 小时前
Kafka Streams 窗口统计怎么验收:本地跑订单流聚合,用 cpolar 给同事看只读结果页
java·docker·kafka·cpolar·kafka streams
爱读源码的大都督7 小时前
DeepSeek面试官问:生产RAG系统回答不准确,该如何定位和优化?这样回答,能让面试官当场给你Offer!
java·后端·python
杨运交8 小时前
[069][公共模块]Spring Boot 全局异常处理与参数校验实战(下):校验异常精细化处理与 WebFlux 适配
java·spring boot·后端
Raas1008 小时前
MAI Gateway(魔芋企业级AI网关)对比分析:AI网关和OpenRouter区别?企业级能力差距一览
java·服务器·网络·人工智能·gateway·ai网关·mai gateway
APItesterCris8 小时前
告别人工盯品!借助 Open‑Claw 快速搭建电商商品全自动监控与数据分析系统(完整实操代码)
java·大数据·前端·数据库
青山木8 小时前
Hot 100 --- 跳跃游戏 II
java·数据结构·算法·leetcode·贪心算法
ly76898 小时前
Spring 中的 @Configuration 与 @Component 差异:为何代理时机决定 Bean 生命周期行为
java·后端·spring·注解·代理·bean生命周期
qq_452396238 小时前
第十二篇:《数据采集:Grafana Alloy、Fluent Bit、Vector 的选型与配置》
java·贪心算法·grafana
珍珠先生9 小时前
P16 · IDEA 启动报错:找不到或无法加载主类
java