Beego ORM 查询字段为 NULL 的记录需用 Filter("字段名__isnil", true),其中双下划线分隔且参数必须为 true;字段结构体 tag 必须含 orm:"null",否则条件无效。

Beego ORM 如何查询字段为 NULL 的记录
Beego 的 orm.QuerySeter 不支持直接用 IsNull 方法(那是 Django ORM 的写法),它用的是 IsNil 来表达“字段值为 NULL”——注意拼写是 IsNil,不是 IsNull,这是最常踩的坑。
使用 IsNil 查询 NULL 值的正确写法
IsNil 是 Beego ORM 提供的专用条件方法,只接受一个参数:字段名字符串。它生成的 SQL 是 WHERE field IS NULL。
示例(查 User 表中 phone 为 NULL 的用户):
o := orm.NewOrm()
var users []*User
qs := o.QueryTable(&User{})
qs.Filter("phone__isnil", true).All(&users)
关键点:
-
Filter的键名格式是"字段名__isnil",双下划线分隔,固定写死,不能写成is_null或isnil - 第二个参数必须是
true(传false会报错或被忽略,Beego 不支持IsNotNil的反向语法) - 该条件仅对数据库中真实存储为
NULL的字段生效;空字符串""、零值0、false都不算
常见错误现象和排查建议
如果查不到预期数据,大概率是以下原因:
- 数据库字段实际存的是空字符串
""而非NULL→ 改用Filter("phone", "") - 结构体字段 tag 没配好,导致 ORM 映射失败 → 检查
orm:"null"是否加在对应字段上(如Phone string `orm:"null"`) - 用了
IsNil函数(Beego 没这个函数)或手写 SQL 拼了IS NULL但没用Raw→ 混淆了 ORM 接口和原生 SQL - MySQL 中字段定义为
NOT NULL DEFAULT ''→ 数据库层面就不可能有 NULL,得先改表结构
需要同时查 NULL 和空字符串怎么办
Beego ORM 不支持 OR 条件链式调用,只能拆成两次查询再合并,或改用 Raw:
o.Raw("SELECT * FROM user WHERE phone IS NULL OR phone = ?", "").QueryRows(&users)
注意:Raw 返回的是 sql.Rows,需手动 Scan;若坚持用 ORM,就得用两次 Filter + append 合并切片,但要注意去重和性能。
真正容易被忽略的是:Beego 的 IsNil 只作用于可为空的字段(即 struct tag 含 orm:"null"),如果字段没声明 null,即使数据库里是 NULL,ORM 也可能默认赋零值后忽略该条件。


















