MyBatis-Plus中isNull与SQL语法详解:处理空值的正确姿势
MyBatis-Plus中isNull与SQL语法详解:处理空值的正确姿势
在使用MyBatis-Plus或直接操作SQL时,处理空值(NULL)和空字符串(“”)经常引发混淆和问题。本文将通过实战案例,详细分析为何
yard_location IS NULL和yard_location = NULL会返回不同结果,以及在 MyBatis-Plus 中如何正确使用isNull方法来查询空值。
前言
在数据库中,NULL 表示没有值,这是一种特殊的标记。它与空字符串(“”)或数字 0 是不同的。在处理数据库查询时,正确区分和处理 NULL 值是非常重要的。
什么是 NULL?
NULL 表示数据库中没有值,是一种特殊的标记。它与空字符串(“”)或数字 0 是不同的。
如何查询 NULL?
查询字段是否为 NULL 应使用 IS NULL 或 IS NOT NULL。例如:
SELECT * FROM dangerous_goods_log WHERE yard_location IS NULL;
而 yard_location = NULL 是无效的,任何值与 NULL 比较(如 =、!=)都返回 UNKNOWN,即不匹配任何结果。
MyBatis-Plus 查询:为何 .eq("yard_location", "") 返回空数据?
在 MyBatis-Plus 中,.eq("yard_location", "") 生成的 SQL 类似于:
SELECT * FROM `dangerous_goods_log` WHERE yard_location = '';
这会查询 yard_location 为 空字符串 的记录,而不是 NULL。如果数据库中 yard_location 为 NULL 而非 “”,此查询将不匹配任何结果。
如果使用 .isNull("yard_location"),则生成的 SQL 为:
SELECT * FROM `dangerous_goods_log` WHERE yard_location IS NULL;
这是正确查询 NULL 的方式,因此返回正确结果。
MyBatis-Plus 中处理 NULL 的基本方法
MyBatis-Plus 提供了 isNull 和 isNotNull 方法,用于处理 NULL 值的查询条件。
查询字段值为 NULL 的数据
List<GoodsLogDO> goodsLogs = goodsLogMapper.selectList(
new QueryWrapper<GoodsLogDO>()
.isNull("yard_location") // 查询 yard_location 为 NULL 的记录
.in("dangerous_goods_status", 0L, 1L) // 状态为 0 或 1
);
生成的 SQL:
SELECT * FROM `dangerous_goods_log`
WHERE yard_location IS NULL
AND dangerous_goods_status IN (0, 1);
查询字段值非 NULL 的数据
List<GoodsLogDO> goodsLogs = goodsLogMapper.selectList(
new QueryWrapper<GoodsLogDO>()
.isNotNull("yard_location") // 查询 yard_location 非 NULL 的记录
.eq("dangerous_goods_status", 0L) // 状态为 0
);
生成的 SQL:
SELECT * FROM `dangerous_goods_log`
WHERE yard_location IS NOT NULL
AND dangerous_goods_status = 0;
查询字段为空字符串或 NULL 的记录
List<GoodsLogDO> goodsLogs = goodsLogMapper.selectList(
new QueryWrapper<GoodsLogDO>()
.and(wrapper -> wrapper
.isNull("yard_location") // yard_location 为 NULL
.or()
.eq("yard_location", "") // 或为空字符串
)
.eq("dangerous_goods_status", 1L); // 状态为 1
);
生成的 SQL:
SELECT * FROM `dangerous_goods_log`
WHERE (yard_location IS NULL OR yard_location = '')
AND dangerous_goods_status = 1;
总结
区分 NULL 和空字符串:在数据库中,
NULL和 “” 是不同的。如果需要同时查询两种情况,必须显式使用IS NULL和=条件。MyBatis-Plus 默认行为:MyBatis-Plus 不会自动将空字符串(“”)视为
NULL。SQL 默认比较规则:避免使用
= NULL或!= NULL,改用IS NULL或IS NOT NULL。空值赋值处理:插入数据时,如果字段需要为空,应显式插入
NULL而非 “”,以确保查询逻辑一致。