Beego ORM 的 In() 方法用于生成 SQL IN 子句,需传入非空切片且字段名区分大小写;不支持链式多次 In(),多字段需用 Raw();空切片被忽略,NULL 需显式处理,参数建议不超过 500 个。

Beego ORM 的 QueryTable().In() 基本用法
Beego 的 ORM 不支持直接在 Where() 里写 IN 子句,必须用 In() 方法配合 Filter() 或独立调用。它底层会生成标准 SQL 的 WHERE field IN (?, ?, ?),但要求传入的参数是切片([]interface{} 或具体类型切片),且不能为空。
常见错误:传入 nil 或空切片会导致 panic 或查不到数据;传入单个值(如 int)会编译失败或运行时报 reflect: Call using zero Value。
-
In()必须紧跟QueryTable(&Model{})后调用,不能链式接在Filter()后面再调用(否则被忽略) - 字段名是字符串,区分大小写,对应数据库列名(非结构体字段名),例如数据库列是
user_id,就得写"user_id" - 值切片元素类型需与字段类型兼容,比如数据库是
INT,就别传[]string,否则报cannot convert string to int
传入 []int、[]string 等具体类型切片的写法
最常用也最安全的方式是显式声明切片类型。Beego ORM 能自动识别 []int、[]int64、[]string 等,并正确绑定参数。
示例:查 ID 在列表中的用户
var ids = []int64{1, 5, 9, 12}
var users []User
err := o.QueryTable(&User{}).In("id", ids).All(&users)
if err != nil {
// 处理错误
}
注意:In("id", ids) 中的 ids 不能是 nil,也不能是长度为 0 的切片——此时 ORM 会跳过该条件(不报错但逻辑失效)。如果业务上可能为空,得提前判断:
- 空切片 → 直接返回空结果或跳过查询
- 需要“无匹配”语义,可手动加
Filter("id", 0).Filter("id__gt", 0)这类矛盾条件来短路
动态构建多个 In 条件或混合其他过滤
Beego ORM 不支持一次调用多个 In()(比如同时对 status 和 category 做 IN 查询),必须拆成多次 Filter() + In() 组合,且 In() 只能作用于一个字段。
若要实现多字段 IN,只能拼 SQL(用 Raw())或分步查后内存过滤。例如:
// ❌ 错误:以下写法第二个 In() 会被忽略
o.QueryTable(&User{}).In("status", statusList).In("category", catList)
<p>// ✅ 正确:用 Raw 手动写(注意 SQL 注入!务必用参数化)
var users []User
o.Raw("SELECT * FROM user WHERE status IN (?) AND category IN (?)", statusList, catList).QueryRows(&users)</p>
混合使用时,In() 和 Filter() 可共存,顺序无关,ORM 会合并为 AND 条件:
-
QueryTable(...).Filter("deleted", false).In("id", ids)→WHERE deleted = ? AND id IN (?, ?, ?) - 但
Filter("name__in", [...]string{...})是无效的,__in查找符只在Filter()中用于字符串字段的模糊匹配,不是In()替代品
空值、NULL 和性能注意事项
数据库字段含 NULL 时,In() 不会匹配到它们——因为 NULL NOT IN (1,2,3) 永远为 UNKNOWN,SQL 标准下等价于不满足。如果需要包含 NULL,必须显式加 Or() 或改用 Raw():
// 包含 NULL 的等效写法(注意:Or() 不支持嵌套,只能一层)
o.QueryTable(&User{}).In("id", ids).Or("id__isnull", true)
性能方面:In() 参数超过 1000 个时,MySQL 会报 Packet too large 或触发优化器退化;PostgreSQL 对 IN 列表长度更敏感。生产环境建议:
- 单次
In不超过 500 个值 - 超量时拆成多次查询并用
map[int]struct{}去重合并 - 高频大列表场景,优先考虑中间表关联或 Redis 缓存 ID 集合
真正容易被忽略的是:Beego ORM 的 In() 不做去重,也不校验重复值——传入 []int{1,1,2} 会生成 IN (1,1,2),虽然 SQL 语义不变,但可能暴露业务逻辑缺陷。











