Beego ORM 查询字段为 NULL 的记录应使用 qs.Filter("field__isnull", true),语义清晰、兼容性好;qs.Filter("field", "null") 仅旧版支持,不推荐。

Beego ORM 如何查询字段为 NULL 的记录
Beego 的 orm.QuerySeter 默认不支持直接用 nil 或 NULL 作为查询值,写 qs.Filter("field", nil) 会报错或静默忽略。正确方式是使用特殊字符串 "null"(小写)触发底层 SQL 的 IS NULL 语句。
-
qs.Filter("name__isnull", true)是最推荐的写法,语义清晰且兼容性好 -
qs.Filter("name", "null")在旧版 Beego( - 注意字段名必须是模型定义的字段名,不是数据库列名(除非显式设置了
columntag)
Beego ORM 查询非空(NOT NULL)数据的写法
和空值查询对称,但容易误用:qs.Filter("field__isnull", false) 才表示“该字段不为 NULL”,而不是用 __isnull 加 != 或 __ne。
- 错误示例:
qs.Filter("name__ne", "")只排除空字符串,不处理 NULL - 错误示例:
qs.Filter("name__isnull", "false")——__isnull后必须接布尔值,传字符串会失效 - 若需同时排除 NULL 和空字符串,得组合条件:
qs.Exclude("name__isnull", true).Exclude("name", "")
联合查询时 NULL 判断的坑:WHERE 子句优先级
Beego ORM 的 Filter 和 Exclude 生成的 SQL 是 AND 连接,但 NULL 判断逻辑在 SQL 层有特殊性——NULL = NULL 返回 false,必须用 IS NULL。ORM 封装了这点,但组合多个 __isnull 条件时仍要小心。
- 例如:
qs.Filter("a__isnull", true).Filter("b__isnull", false)会生成WHERE a IS NULL AND b IS NOT NULL,没问题 - 但若混用:
qs.Filter("a", "null").Filter("b__isnull", false),不同 Beego 版本可能生成不一致的 SQL,建议统一用__isnull - 涉及
LeftJoin时,关联表字段为 NULL 的判断也适用同一规则,无需额外处理
MySQL/PostgreSQL 下 NULL 查询的实际表现差异
Beego ORM 生成的 IS NULL 语句在主流数据库都标准,但实际执行效果受字段是否允许 NULL、索引类型影响。
- 如果字段定义为
NOT NULL,哪怕没设默认值,__isnull查询永远返回空结果 - MySQL 中,B+ 树索引不存储 NULL 值,所以
WHERE col IS NULL无法走索引(除非是组合索引且 NULL 在前导列) - PostgreSQL 对 NULL 索引支持更好,但 Beego 不会自动加
IS NULL的索引提示,得手动优化
真正容易被忽略的是:Beego 模型字段如果用了指针类型(如 *string),数据库存 NULL 时 Go 值是 nil;但如果字段是普通 string 类型,数据库 NULL 会被 ORM 自动转成空字符串 "" —— 此时 __isnull 查询将查不到任何记录,必须改字段类型或调整数据库约束。


















