MyBatis中判断非空字符串与非null为何使用and而非or?
为什么MyBatis的
<if>标签判断非空和非空字符串要用AND而不是OR? 问题描述
我想要在MyBatis的SQL更新语句里,仅当m_name字段有值(既不是null也不是空字符串)时才更新它。一开始我用了这个条件:
<if test="m_name !='' or m_name !=null">
但这个条件完全不生效——不管m_name是null还是空字符串,都会进入这个分支执行更新。后来我把条件改成了:
<if test="m_name !='' and m_name !=null">
对应的完整更新语句就正常工作了:
update menu01 <set> <if test="m_name !='' and m_name !=null"> m_name = #{m_name} </if> </set>
我有点困惑:null和空字符串是互斥的,一个值不可能同时既是null又是空字符串,为什么这里必须用AND而不是OR呢?
解答
这其实是逻辑判断里的常见误区,咱们一步步拆解就能明白:
首先明确你的核心需求:只有当m_name同时满足「不是null」和「不是空字符串」这两个条件时,才执行更新——换句话说,两个条件必须同时成立,才符合触发更新的要求。
咱们来分别看两种逻辑的实际效果:
当用
OR时:- 如果
m_name是null:m_name !=''这个判断会返回true(因为MyBatis中null和空字符串不属于同一类,比较结果为真),而m_name !=null是false。但OR的逻辑是「只要有一个条件为真,整个表达式就为真」,所以此时会进入if分支,违背你的需求。 - 如果
m_name是空字符串:m_name !=null是true,m_name !=''是false,同样OR会让整个表达式为真,还是会进入分支,也不符合要求。
- 如果
当用
AND时:- 如果
m_name是有效值(比如"首页菜单"):m_name !=null和m_name !=''都为true,整个表达式为真,执行更新,符合需求。 - 如果
m_name是null:m_name !=null为false,整个表达式直接为假,跳过更新。 - 如果
m_name是空字符串:m_name !=''为false,整个表达式也为假,跳过更新。
- 如果
刚好完美匹配你「仅当字段有值时更新」的需求。
另外补充个实用小技巧:如果要同时处理全空格的情况(比如m_name是" "),可以把条件改成m_name != null and m_name.trim() != '';如果用的是MyBatis 3.5及以上版本,还可以直接用内置工具类简化:StringUtils.isNotBlank(m_name),代码会更简洁。
内容的提问来源于stack exchange,提问作者ungjang
相关产品推荐
相关产品推荐

