xml 取值错误 #{} boolean 一直为 false

取值时

#{param.msgStatus} 一直是false,java代码里面显示true。

 <select id="findPageOaReading" resultType="com.focusin.data.office.func.dto.ProcessMessageInfoDTO">
        select i.*, t.template_name procdefName
        from process_message_info i
                          inner join process_oa_template t on i.process_oa_template_id = t.id
        where i.del_flag = 0 and i.status = 1

            and i.receive_user = #{param.receiveUser}
            and i.data_type in (1, 2, 3, 4)
            and i.msg_status = #{param.msgStatus}
            <if test="param.processTitle!=null and param.processTitle!=''">
                and i.process_title like concat(#{param.processTitle}, '%')
            </if>
            <if test="param.tenant!=null and param.tenant!=''">
                and i.tenant = #{param.tenant}
            </if>

            <if test="param.sendUser!=null and param.sendUser!=''">
                and i.send_user = #{param.sendUser}
            </if>

            <if test="param.templateName!=null and param.templateName!=''">
                and t.template_name like CONCAT(#{param.templateName},'%')
            </if>

        <if test="param.receiveBeginTime!=null and param.receiveEndTime!=null">
            and i.create_time between #{param.receiveBeginTime} and #{param.receiveEndTime}
        </if>
        <if test="param.msgStatus == true and param.operateBeginTime!=null and param.operateEndTime!=null">
            and i.update_time between #{param.operateBeginTime} and #{param.operateEndTime}
        </if>


    </select>

问题原因:判断boolean类型时不能用 param.msgStatus = 1 ,不然会使得 #{param.msgStatus} 取值一直为false

在这里插入图片描述

<think>根据用户需求,用户询问在MyBatis中如何使用<if>标签测试Boolean类型条件,并寻求正确写法。结合提供的引用内容,我们需要特别注意MyBatis在处理Boolean类型的特殊规则。 关键点分析: 1. 引用[1][2][4][5]指出:MyBatis使用OGNL表达式解析<if>标签的test属性,而OGNL对Boolean类型的处理有特殊规则。 2. 引用[1]警告:不要直接使用Boolean类型的变量,因为MyBatis会把Boolean类型转为false。这可能导致前端传,条件永远为false。 3. 引用[4][5]详细说明了OGNL的解析规则: - 如果对象是Boolean,则直接取其。 - 如果对象是Number(包括整型、浮点型),则非0为true,0为false。 - 如果对象是Character,非0字符为true。 - 其他非null对象为true。 因此,对于Boolean类型的条件,我们需要注意: - 避免使用基本类型boolean,因为基本类型有默认false,可能无法区分前端是否传。 - 建议使用包装类型Boolean,这样我们可以检查null(即前端的情况)。 - 在<if>标签中,直接使用Boolean变量即可,因为OGNL会正确解析Boolean对象。 正确写法示例: 假设我们有一个Boolean类型的参数`isActive`,我们想根据它来添加条件。 错误写法(直接使用基本类型boolean,且无法处理): <if test="isActive"> ... </if> // 如果前端,基本类型boolean默认为false,条件不成立,但可能我们想处理的是就不加条件 正确写法(使用包装类型Boolean): <if test="isActive != null and isActive"> ... </if> // 先判断不为null,再判断为true <if test="isActive != null and !isActive"> ... </if> // 判断为false的情况 但是,注意引用[1]中提到的:如果前端传,MyBatis会把Boolean转为false。所以,如果我们使用包装类型Boolean,前端传(null),在MyBatis中会变成null还是false?实际上,这里涉及参数映射。如果我们的参数是一个Boolean对象,前端传,那么它应该是null。所以我们可以用null来判断。 然而,引用[1]中警告不要使用boolean类型的原因在于:如果字段是基本类型boolean,那么前端传,MyBatis会将其设置为默认false(因为基本类型不能为null),这样我们就无法区分是前端传了false还是没传。 因此,总结: 1. 在Java的DTO中,使用包装类型Boolean(即Boolean,而不是boolean)来接收前端参数。 2. 在<if>标签中,先判断是否为null,再根据true/false来写条件。 示例代码: 假设我们有一个查询,根据用户是否激活(isActive)来过滤数据。 Java DTO: public class UserQuery { private Boolean isActive; // getter and setter } XML映射文件: <select id="selectUsers" resultType="User"> SELECT * FROM user <where> <!-- 当isActive不为null且为true,添加条件 --> <if test="isActive != null and isActive"> AND active = 1 </if> <!-- 当isActive不为null且为false --> <if test="isActive != null and !isActive"> AND active = 0 </if> </where> </select> 这样,如果前端没有传isActive参数(即null),那么两个条件都不会加入,查询所有状态的用户。 如果前端传了isActive=true,则只查询active=1的用户;传false则只查询active=0的用户。 另外,引用[3]提到了一种优化,使用<choose>标签,但在这个场景下,我们使用两个<if>标签已经可以满足。 注意:如果数据库中的active字段是数字类型(比如0和1),那么上面的写法是合适的。如果数据库中是布尔类型(比如MySQL的TINYINT(1)),也可以这样处理。 引用[2][5]还提到,OGNL会把0视为false,非0视为true。因此,如果我们错误地将一个整型变量当作布尔条件使用,可能会出现问题。所以,确保在布尔条件中使用的是布尔类型,而不是整型。 因此,用户的问题“MyBatis <if> 标签判断 Boolean 类型的正确写法”的答案就是: - 使用包装类型Boolean(而非基本类型boolean)作为参数类型。 - 在<if>标签中,先判断非,再判断布尔。 生成相关问题: 1. 为什么在MyBatis中不建议使用基本类型boolean作为条件判断? 2. 除了Boolean类型,MyBatis的<if>标签还支持哪些类型的条件判断? 3. 如何避免MyBatis动态SQL中因类型转换导致错误?</think>在 MyBatis 中使用 `<if>` 标签判断 Boolean 类型,需特别注意 **OGNL 表达式解析规则**和**处理**。以下是正确写法和关键注意事项: --- ### ✅ 正确写法示例 ```xml <!-- 使用包装类型 Boolean(非基本类型 boolean) --> <if test="isActive != null and isActive"> AND status = 1 </if> <!-- 判断 false --> <if test="isDeleted != null and !isDeleted"> AND deleted = 0 </if> ``` --- ### ⚠️ 关键注意事项 1. **必须使用包装类型 `Boolean`** - ❌ 禁止基本类型 `boolean`:若前端传,MyBatis 会默认转为 `false`,导致逻辑错误[^1][^2]。 - ✅ 正确做法:Java 字段声明为 `Boolean`(允许 `null` )。 2. **必须显式判** OGNL 将 `null` 视为 `false`,但需避免指针问题: ```xml <!-- 错误:若 isActive=null 会跳过条件 --> <if test="isActive"> ... </if> <!-- 正确:先判取值 --> <if test="isActive != null and isActive"> ... </if> ``` 3. **避免与数字类型混淆** OGNL 解析规则:非零数字 = `true`,零 = `false`[^4][^5]。 ```xml <!-- 危险:若 type=0 会被解析为 false --> <if test="type"> ... </if> <!-- 安全:明确判断布尔 --> <if test="isValid != null and isValid"> ... </if> ``` --- ### 📝 完整示例 **Java 实体类**: ```java public class UserQuery { private Boolean isActive; // 包装类型 Boolean private Boolean isDeleted; // Getters & Setters } ``` **Mapper XML**: ```xml <select id="selectUsers" resultType="User"> SELECT * FROM user <where> <!-- 判断 true --> <if test="isActive != null and isActive"> AND status = 1 </if> <!-- 判断 false --> <if test="isDeleted != null and !isDeleted"> AND deleted = 0 </if> </where> </select> ``` --- ### ⚡ 优化建议 1. **使用 `<choose>` 处理多状态** 当需区分 `true`/`false`/`null` : ```xml <choose> <when test="isActive == true">AND status = 1</when> <when test="isActive == false">AND status = 0</when> <otherwise>AND status IN (0,1)</otherwise> <!-- 默认行为 --> </choose> ``` 2. **替代方案:枚举或字符串** 若需兼容复杂场景(如三态逻辑),可用枚举或字符串代替: ```java public class UserQuery { private String activeStatus; // : "TRUE", "FALSE", "ALL" } ``` ```xml <if test="activeStatus == &#39;TRUE&#39;"> ... </if> ``` --- ### 💡 总结原则 | 场景 | 正确做法 | 错误做法 | |-----------------------|---------------------------------------|------------------------| | **字段类型** | 使用 `Boolean`(包装类型) | 使用 `boolean` | | **判** | `test="param != null and param"` | `test="param"` | | **判断 `false`** | `test="param != null and !param"` | `test="!param"` | | **数字型条件** | 显式比较:`test="num > 0"` | 依赖隐式转换 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

dlage

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

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

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

打赏作者

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

抵扣说明:

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

余额充值