Room(SQLite)带Null参数的WHERE子句查询失效问题排查
问题原因分析
你碰到的这个问题其实是SQL的基础规则导致的——在SQL中,不能用=来判断NULL值。因为NULL代表的是“未知值”,任何和NULL的比较(包括feature = NULL)都会返回UNKNOWN,而不是TRUE,所以你的查询在传入null时自然找不到对应的记录。
解决方案
你只需要修改PersonDao中的查询语句,让它能同时处理普通值和NULL的情况,这里有两种常用的写法:
写法一:分支判断匹配NULL
直接在SQL里加入对参数为NULL的判断,当参数是NULL时,用IS NULL匹配表中的NULL记录:
@Dao public interface PersonDao { // ... 其他方法保持不变 @Query("SELECT * FROM person WHERE feature = :feature OR (:feature IS NULL AND feature IS NULL)") List<Person> getByFeature(String feature); }
写法二:使用COALESCE函数(可选)
如果你觉得上面的写法有点啰嗦,也可以用COALESCE函数把NULL转换成一个特殊的占位值来匹配,比如:
@Query("SELECT * FROM person WHERE COALESCE(feature, '###NULL###') = COALESCE(:feature, '###NULL###')") List<Person> getByFeature(String feature);
这个思路是把所有NULL都替换成一个不会出现在真实数据里的字符串,这样就能用普通的=来匹配了。
验证修改效果
修改完DAO之后,你的测试代码里最后一行assertEquals(null, dao.getByFeature(null).get(0).getFeature());就能正常通过了,因为现在查询会正确匹配表中feature为NULL的那条记录。
内容的提问来源于stack exchange,提问作者Egis
相关产品推荐
相关产品推荐

