Mybatis中xml的有关if test以及==的用法

本文详细解析了在MyBatis中如何处理复杂的SQL语句,特别是在mapper.xml文件中结合页面查询筛选条件,使用<if test>进行动态SQL生成的方法。并通过一个具体的例子展示了如何在SQL中加入条件判断,确保SQL的灵活性与准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mybatis中,通常都要在mapper.xml中写复杂的sql语句,结合页面的查询筛选条件,需要在sql语句中加入

<if test=""></if>等的判断。而这test 后面的字段也是来自jsp或者html页面,但是不是随便书写的。

在这里插入图片描述
在这里插入图片描述
与页面都要一一对应,除此之外,还需要在实体类中有定义。
在这里插入图片描述
另外,mybatis中 <if test=>等于的条件怎么写?

注意 仅仅需要将双引号和单引号的位置换一下即可!!! 
在这里插入图片描述

<sql id="queryData">
	select '集团' src_dbct_cd,
	substr(stats_mo,1,4) year,
	substr(stats_mo,5,6) month,
	sum(all_zb_cars) all_zb_cars,sum(all_kb_cars) all_kb_cars,sum(all_wd_cars) all_wd_cars,
	sum(all_zb_cars+all_kb_cars+all_wd_cars) all_cars_total,
	sum(round(all_zb_exp/10000,2)) all_zb_exp,sum(round(all_kb_exp/10000,2))
	all_kb_exp,sum(round(all_wd_exp/10000,2)) all_wd_exp,
	sum(round(all_zb_exp/10000+all_kb_exp/10000+all_wd_exp/10000,2))
	all_exp_total,
	sum(zb_cars) zb_cars,sum(kb_cars) kb_cars,
	sum(zb_cars+kb_cars) cars_total,
	sum(round(zb_net_wgt/10000000,2)) zb_net_wgt,sum(round(kb_net_wgt/10000000,2)) kb_net_wgt,
	sum(round(ifnull(zb_net_wgt/10000000,0)+ifnull(kb_net_wgt/10000000,0),2))
	wgt_total,
	sum(round(zb_exp/10000,2)) zb_exp,sum(round(kb_exp/10000,2)) kb_exp,
	sum(round(zb_exp/10000+kb_exp/10000,2)) exp_total,
	sum(zb_lod_mnt) zb_lod_mnt,sum(kb_lod_mnt) kb_lod_mnt,
	sum(ifnull(zb_lod_mnt,0)+ifnull(kb_lod_mnt,0)) lod_mnt_total,
	sum(zb_wait_mnt) zb_wait_mnt,sum(kb_wait_mnt) kb_wait_mnt,
	sum(ifnull(zb_wait_mnt,0)+ifnull(kb_wait_mnt,0)) wait_mnt_total,
	concat(round(sum(zb_dlyd_cars/zb_cars)*100,2),'%') zb_dlyd_pt,
	concat(round(sum(kb_dlyd_cars/kb_cars)*100,2),'%') kb_dlyd_pt,
	concat(round(sum(ifnull(zb_dlyd_cars/zb_cars,0)+ifnull(kb_dlyd_cars/kb_cars,0))*100,2),'%')
	dlyd_pt_total,
	concat(round(sum(zb_frqc_dlyd_cars/zb_cars)*100,2),'%') zb_frqc_dlyd,
	concat(round(sum(kb_frqc_dlyd_cars/kb_cars)*100,2),'%') kb_frqc_dlyd,
	concat(round(sum(ifnull(zb_frqc_dlyd_cars/zb_cars,0)+ifnull(kb_frqc_dlyd_cars/kb_cars,0))*100,2),'%')
	frqc_dlyd_total,
	sum(zb_dlyd_mnt) zb_dlyd_mnt,sum(kb_dlyd_mnt) kb_dlyd_mnt,
	sum(ifnull(zb_dlyd_mnt,0)+ifnull(kb_dlyd_mnt,0)) dlyd_mnt_total,
	round(ifnull(sum(zb_sys_mlg)/sum(zb_stip_mnt),0),2) zb_stip_speed,
	round(ifnull(sum(kb_sys_mlg)/sum(kb_stip_mnt),0),2) kb_stip_speed,
	(round(ifnull(sum(zb_sys_mlg)/sum(zb_stip_mnt),0)+ifnull(sum(kb_sys_mlg)/sum(kb_stip_mnt),0),2))
	stip_speed_total,
	round(ifnull(sum(zb_est_mlg)/sum(zb_actl_mnt),0),2) zb_actl_speed,
	round(ifnull(sum(kb_est_mlg)/sum(kb_actl_mnt),0),2) kb_actl_speed,
	(round(ifnull(sum(zb_est_mlg)/sum(zb_actl_mnt),0)+ifnull(sum(kb_est_mlg)/sum(kb_actl_mnt),0),2))
	actl_speed_total,
	sum(round(zb_pnlt/10000,2)) zb_pnlt,sum(round(kb_pnlt/10000,2)) kb_pnlt,
	sum(ifnull(round(zb_pnlt/10000,2),0)+ifnull(round(kb_pnlt/10000,2),0))
	pnlt_total,
	sum(zb_uld_wait_mnt) zb_uld_wait_mnt,sum(kb_uld_wait_mnt) kb_uld_wait_mnt,sum(wd_uld_wait_mnt) wd_uld_wait_mnt,
	round((ifnull(sum(zb_uld_wait_mnt),0)+ifnull(sum(kb_uld_wait_mnt),0)+ifnull(sum(wd_uld_wait_mnt),0))/
	(ifnull(sum(all_zb_cars),0)+ifnull(sum(all_kb_cars),0)+ifnull(sum(all_wd_cars),0)),2)
	uld_wait_mnt_total,
	sum(zb_uld_mnt) zb_uld_mnt,sum(kb_uld_mnt) kb_uld_mnt,sum(wd_uld_mnt) wd_uld_mnt,
	sum(ifnull(zb_uld_mnt,0)+ifnull(kb_uld_mnt,0)+ifnull(wd_uld_mnt,0)) uld_mnt_total,
	concat(round(sum(zb_brk_cars/zb_mlg/10000)*100,2),'%') zb_brk_cars,
	concat(round(sum(kb_brk_cars/kb_mlg/10000)*100,2),'%') kb_brk_cars,
	concat(round(sum(wd_brk_cars/wd_mlg/10000)*100,2),'%') wd_brk_cars,
	concat((round(sum(ifnull(zb_brk_cars/zb_mlg/10000,0)+ifnull(kb_brk_cars/kb_mlg/10000,0)+ifnull(wd_brk_cars/wd_mlg/10000,0))*100,2)),'%')
	brk_cars_total,
	concat(round(sum(zb_accdt_cars/zb_mlg/10000)*100,2),'%') zb_accdt_cars,
	concat(round(sum(kb_accdt_cars/kb_mlg/10000)*100,2),'%') kb_accdt_cars,
	concat(round(sum(wd_accdt_cars/wd_mlg/10000)*100,2),'%') wd_accdt_cars,
	concat((round(sum(ifnull(zb_accdt_cars/zb_mlg/10000,0)+ifnull(kb_accdt_cars/kb_mlg/10000,0)+ifnull(wd_accdt_cars/wd_mlg/10000,0))*100,2)),'%')
	accdt_cars_total,
	concat(round(sum(actl_tms/stip_tms)*100,2),'%') tms_total
	from bdrpt.kd_car_trans_mont_stats
	where 1=1
	<if test="stats_mo != null and stats_mo != ''" >
	and concat(SUBSTR(stats_mo,1,4),'-',SUBSTR(stats_mo,5,6))=#{stats_mo}
	</if> 
	<if test='SRC_DBCT_CD == "2"'>
	and src_dbct_cd = '分拨'
	</if>
	GROUP BY substr(stats_mo,5,6) 
	UNION 
	select l.location_name src_dbct_cd,
	substr(stats_mo,1,4) year,
	substr(stats_mo,5,6) month,
	all_zb_cars,all_kb_cars,all_wd_cars,
	(all_zb_cars+all_kb_cars+all_wd_cars) all_cars_total,
	round(all_zb_exp/10000,2) all_zb_exp,round(all_kb_exp/10000,2)
	all_kb_exp,round(all_wd_exp/10000,2) all_wd_exp,
	round(all_zb_exp/10000+all_kb_exp/10000+all_wd_exp/10000,2)
	all_exp_total,
	zb_cars,kb_cars,
	(zb_cars+kb_cars) cars_total,
	round(zb_net_wgt/10000000,2) zb_net_wgt,round(kb_net_wgt/10000000,2) kb_net_wgt,
	round(ifnull(zb_net_wgt/10000000,0)+ifnull(kb_net_wgt/10000000,0),2)
	wgt_total,
	round(zb_exp/10000,2) zb_exp,round(kb_exp/10000,2) kb_exp,
	round(zb_exp/10000+kb_exp/10000,2) exp_total,
	zb_lod_mnt,kb_lod_mnt,
	(ifnull(zb_lod_mnt,0)+ifnull(kb_lod_mnt,0)) lod_mnt_total,
	zb_wait_mnt,kb_wait_mnt,
	(ifnull(zb_wait_mnt,0)+ifnull(kb_wait_mnt,0)) wait_mnt_total,
	concat(round(zb_dlyd_cars/zb_cars*100,2),'%') zb_dlyd_pt,
	concat(round(kb_dlyd_cars/kb_cars*100,2),'%') kb_dlyd_pt,
	concat(round((ifnull(zb_dlyd_cars/zb_cars,0)+ifnull(kb_dlyd_cars/kb_cars,0))*100,2),'%')
	dlyd_pt_total,
	concat(round(zb_frqc_dlyd_cars/zb_cars*100,2),'%') zb_frqc_dlyd,
	concat(round(kb_frqc_dlyd_cars/kb_cars*100,2),'%') kb_frqc_dlyd,
	concat(round((ifnull(zb_frqc_dlyd_cars/zb_cars,0)+ifnull(kb_frqc_dlyd_cars/kb_cars,0))*100,2),'%')
	frqc_dlyd_total,
	zb_dlyd_mnt,kb_dlyd_mnt,
	(ifnull(zb_dlyd_mnt,0)+ifnull(kb_dlyd_mnt,0)) dlyd_mnt_total,
	round(ifnull(sum(zb_sys_mlg)/sum(zb_stip_mnt),0),2) zb_stip_speed,
	round(ifnull(sum(kb_sys_mlg)/sum(kb_stip_mnt),0),2) kb_stip_speed,
	(round(ifnull(sum(zb_sys_mlg)/sum(zb_stip_mnt),0)+ifnull(sum(kb_sys_mlg)/sum(kb_stip_mnt),0),2))
	stip_speed_total,
	round(ifnull(sum(zb_est_mlg)/sum(zb_actl_mnt),0),2) zb_actl_speed,
	round(ifnull(sum(kb_est_mlg)/sum(kb_actl_mnt),0),2) kb_actl_speed,
	(round(ifnull(sum(zb_est_mlg)/sum(zb_actl_mnt),0)+ifnull(sum(kb_est_mlg)/sum(kb_actl_mnt),0),2))
	actl_speed_total,
	round(zb_pnlt/10000,2) zb_pnlt,round(kb_pnlt/10000,2) kb_pnlt,
	(ifnull(round(zb_pnlt/10000,2),0)+ifnull(round(kb_pnlt/10000,2),0))
	pnlt_total,
	zb_uld_wait_mnt,kb_uld_wait_mnt,wd_uld_wait_mnt,
	round((ifnull(sum(zb_uld_wait_mnt),0)+ifnull(sum(kb_uld_wait_mnt),0)+ifnull(sum(wd_uld_wait_mnt),0))/
	(ifnull(sum(all_zb_cars),0)+ifnull(sum(all_kb_cars),0)+ifnull(sum(all_wd_cars),0)),2)
	uld_wait_mnt_total,
	zb_uld_mnt,kb_uld_mnt,wd_uld_mnt,
	(ifnull(zb_uld_mnt,0)+ifnull(kb_uld_mnt,0)+ifnull(wd_uld_mnt,0)) uld_mnt_total,
	concat(round(zb_brk_cars/zb_mlg/10000*100,2),'%') zb_brk_cars,
	concat(round(kb_brk_cars/kb_mlg/10000*100,2),'%') kb_brk_cars,
	concat(round(wd_brk_cars/wd_mlg/10000*100,2),'%') wd_brk_cars,
	concat((round((ifnull(zb_brk_cars/zb_mlg/10000,0)+ifnull(kb_brk_cars/kb_mlg/10000,0)+ifnull(wd_brk_cars/wd_mlg/10000,0))*100,2)),'%')
	brk_cars_total,
	concat(round(zb_accdt_cars/zb_mlg/10000*100,2),'%') zb_accdt_cars,
	concat(round(kb_accdt_cars/kb_mlg/10000*100,2),'%') kb_accdt_cars,
	concat(round(wd_accdt_cars/wd_mlg/10000*100,2),'%') wd_accdt_cars,
	concat((round((ifnull(zb_accdt_cars/zb_mlg/10000,0)+ifnull(kb_accdt_cars/kb_mlg/10000,0)+ifnull(wd_accdt_cars/wd_mlg/10000,0))*100,2)),'%')
	accdt_cars_total,
	concat(round(actl_tms/stip_tms*100,2),'%') tms_total
	from bdrpt.kd_car_trans_mont_stats t LEFT JOIN bdkdbase.location l on t.src_dbct_cd = l.location_xid
	where 1=1
	<if test="stats_mo != null and stats_mo != ''" >
	and concat(SUBSTR(stats_mo,1,4),'-',SUBSTR(stats_mo,5,6))=#{stats_mo}
	</if>
	<if test='SRC_DBCT_CD == "1"'>
	and src_dbct_cd = '集团'
	</if>
	<if test="SRC_DBCT_NM != null and SRC_DBCT_NM != ''">
	and src_dbct_cd = #{SRC_DBCT_NM}
	</if>
	GROUP BY src_dbct_cd,substr(stats_mo,5,6)
	</sql>
	
	<!-- 查询数据 -->
	<select id="pageQuery" resultType="map">
	<include refid="queryData"></include>
	</select>
<think>我们正在讨论MyBatis XML映射文件中<if>标签的test条件中使用`==`是否有效的问题。 根据引用内容,我们可以总结以下几点: 1. 引用[1]中提到,在if判断中,当比较字符串和字符时,使用`== '1'`可能不生效,而使用`'1'.toString()`才生效。 2. 引用[3]中提到,对于Integer类型的属性,使用`!= ''`实际上会被OGNL解析为`!=0`,因此当Integer值为0时,条件不成立。 3. 引用[4]提供了两种字符串等于条件的写法:一种是互换双引号和单引号的位置(即外层单引号,内层双引号),另一种是使用`.toString()`方法。 4. 引用[5]提到在test语法中使用`==`判断时遇到问题。 因此,我们可以得出结论:在MyBatis的<if>标签的test属性中,使用`==`是有效的,但是需要注意比较的对象类型和OGNL表达式的解析规则。 具体问题及解决方案: 问题1:字符串比较 - 错误写法:`<if test="state == '1'">`(当state为字符串时,可能不生效) - 正确写法1:互换引号位置:`<if test='state == "1"'>` - 正确写法2:使用toString:`<if test="state == '1'.toString()">` 问题2:数值类型比较 - 对于Integer等数值类型,避免与空字符串比较,因为OGNL会将空字符串`''`转换为0,所以不要使用`status != ''`这样的条件。 - 正确的数值判断:`<if test="status != null">`(不需要判断空字符串) 为什么会出现这些问题? - MyBatis使用OGNL表达式来解析test条件。OGNL对于字符串和字符的处理、以及类型转换有其特定的规则。 - 当使用`state == '1'`时,如果state是字符串类型,那么'1'在OGNL中可能被解释为字符(char),而字符串(String)和字符(char)在Java中是不同的类型,因此比较可能失败。 - 使用`.toString()`可以确保类型明确为字符串,或者互换引号的方式让OGNL将双引号内的内容解释为字符串。 因此,使用`==`是有效的,但必须注意比较双方的类型要匹配。 示例: 1. 字符串比较: ```xml <!-- 推荐写法1:使用双引号包裹字符串 --> <if test='state == "1"'> ... </if> <!-- 推荐写法2:使用toString() --> <if test="state == '1'.toString()"> ... </if> ``` 2. 整数比较: ```xml <!-- 整数比较,直接使用数字,不需要引号 --> <if test="status == 1"> ... </if> ``` 3. 避免整数与空字符串比较: ```xml <!-- 错误:当status为0时,条件不成立 --> <if test="status != null and status != ''"> ... </if> <!-- 正确:整数只需判断null --> <if test="status != null"> ... </if> ``` 总结:在MyBatisif条件判断中,`==`操作符是有效的,但必须注意数据类型和OGNL的解析规则。对于字符串,建议使用上述推荐写法之一;对于数值类型,不要与空字符串比较,只需判断非null即可。 相关问题: 1. MyBatis中如何判断字符串不为空? 2. MyBatisif标签中如何比较两个变量? 3. MyBatis的OGNL表达式支持哪些运算符? 4. 如何避免MyBatis动态SQL中的类型转换错误?</think>在 MyBatisXML 文件中,`<if>` 标签的 `test` 属性中使用 `==` **是有效的**,但需要特别注意数据类型和语法规则,否则可能导致条件判断失效。以下是关键要点和解决方案: --- ### 一、`==` 生效的场景与正确用法 1. **字符串比较**(需使用双引号包裹字符串) ```xml <!-- 正确:外层单引号 + 内层双引号 --> <if test='state == "1"'> AND status = 1 </if> ``` - **错误写法**:`<if test="state == '1'">`(可能失效) 2. **整数比较**(直接使用数字) ```xml <if test="status == 1"> <!-- 无需引号 --> AND status = 1 </if> ``` --- ### 二、`==` 失效的常见原因及解决 #### 1. 数据类型不匹配(根本原因) | 类型 | 错误写法 | 正确写法 | 原因解析 | |--------------|------------------------------|------------------------------|--------------------------------------------------------------------------| | **字符串** | `state == '1'` | `state == "1"` 或 `state == '1'.toString()` | OGNL 将 `'1'` 解析为 `char` 类型,与 `String` 不匹配[^1][^4] | | **Integer** | `status == '1'` | `status == 1` | 字符串 `'1'` 会被 OGNL 转换为 `double` 类型(如 `1.0`),与 `Integer` 不兼容[^3] | | **空值判断** | `status != null and status == ''` | `status != null` | `Integer` 类型判断空字符串时,OGNL 会转成 `0`[^3] | #### 2. 解决方案 - **字符串比较**:使用双引号或 `.toString()` ```xml <!-- 方案1:互换引号 --> <if test='type == "A"'> ... </if> <!-- 方案2:显式调用 toString() --> <if test="type == 'A'.toString()"> ... </if> ``` - **Integer 比较**:避免引号 ```xml <if test="status == 0"> <!-- 直接写数字 --> AND status = 0 </if> ``` --- ### 三、最佳实践与验证方法 #### 1. 统一使用工具类(推荐) ```xml <if test="@com.example.MyBatisUtils@isEqual(type, 'A')"> AND type = 'A' </if> ``` 工具类实现: ```java public class MyBatisUtils { public static boolean isEqual(String str1, String str2) { return str1 != null && str1.equals(str2); } } ``` #### 2. 日志验证 SQL 在 `application.properties` 开启日志: ```properties mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl ``` 检查实际执行的 SQL 是否包含预期条件。 --- ### 四、总结 | 场景 | 正确写法 | 错误写法 | |--------------------|--------------------------------------------------------------------------|------------------------| | **字符串比较** | `test='param == "value"'` 或 `test="param == 'value'.toString()"` | `test="param == 'value'"` | | **Integer 比较** | `test="param == 1"`(无引号) | `test="param == '1'"` | | **空值判断** | `test="param != null"`(Integer 无需判空字符串) | `test="param != ''"` | > 📌 **核心原则**: > 1. 字符串比较用**双引号包裹值** > 2. 数值类型比较**不要加引号** > 3. 避免混合类型比较(如 `String` vs `Integer`) --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

゛Smlie。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值