Beego ORM 不支持直接 LeftJoin 方法,需通过 RelatedSel(依赖正确 rel tag 定义)隐式触发左连接,或使用 Raw 手写 SQL;RelatedSel 默认左连接但无法自定义 ON 条件,复杂场景必须用 Raw 并注意事务隔离与 SQL 兼容性。

Beego ORM 的 LeftJoin 不是直接方法,得用 RelatedSel + 反向关系或原生 SQL
Beego ORM(github.com/astaxie/beego/orm)本身没有暴露 LeftJoin 方法。你调用 QueryTable("user").LeftJoin(...) 会报错:undefined method LeftJoin。它只支持通过模型关系隐式触发左连接(比如 RelatedSel),或者绕过 ORM 走原生 SQL。
RelatedSel 实现左连接效果的条件和限制
当两个模型之间定义了 ForeignKey 关系,并且你在查询主表时用 RelatedSel 加载关联字段,Beego ORM 会在底层生成 LEFT JOIN(前提是数据库驱动支持,MySQL/PostgreSQL 都 OK)。
- 必须在 struct tag 中正确定义
rel(fk)或rel(m2m),且被关联模型有对应ForeignKey字段 -
RelatedSel默认行为是左连接 —— 即使关联记录不存在,主表数据仍会返回(nil值填充关联字段) - 不能自由指定 ON 条件;ON 子句由字段名和 rel tag 自动推导,无法加额外谓词(比如
ON a.status = b.status AND b.deleted = 0) - 不支持多级嵌套
RelatedSel("Profile").RelatedSel("Address")在 v1.x 中可能生成 INNER JOIN,行为不稳定
示例:查用户及其可为空的头像信息
type User struct {
Id int
Name string
AvatarId *int `orm:"null"`
Avatar *Avatar `orm:"rel(fk);null"`
}
type Avatar struct {
Id int
Url string
}
// 这行会生成 LEFT JOIN user.avatar_id = avatar.id
o.QueryTable(&User{}).RelatedSel("Avatar").All(&users)
需要自定义 ON 条件?只能用 Raw 手写 SQL
一旦要控制连接条件、混合多个左连接、或关联非标准外键字段,RelatedSel 就不够用了。这时必须用 Raw + QueryRow/ValuesList 等。
-
Raw返回的是*Orm,不是QuerySeter,不支持链式Limit/OrderBy,得把完整 SQL 写全 - 参数占位符统一用
?(无论 MySQL 还是 PostgreSQL),Beego 会自动适配 - 结果映射需手动处理:用
ValuesList得到 [][][]string,或用QueryRow+ struct 指针(字段名需完全匹配 SQL 别名)
示例:查用户及他们的最新订单(按 order.created 排序取第一条),用 LEFT JOIN + 子查询模拟
var users []map[string]interface{}
sql := `SELECT u.id, u.name, o.id as order_id, o.amount
FROM user u
LEFT JOIN (
SELECT order_id, user_id, amount,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created DESC) rn
FROM order
) o ON u.id = o.user_id AND o.rn = 1`
o.Raw(sql).ValuesList(&users)
容易忽略的坑:事务中 RelatedSel 可能复用连接,Raw 不受事务控制
Beego ORM 的 Raw 查询默认走独立数据库连接,即使你在 Begin() 后调用,它也不会跑在当前事务里 —— 数据一致性可能出问题。
- 如果必须在事务中执行带 JOIN 的查询,别用
Raw,改用QueryTable().Filter().RelatedSel()组合,确保走同一个Ormer实例 -
RelatedSel("X").RelatedSel("Y")在复杂场景下可能生成笛卡尔积,务必检查生成的 SQL(开启orm.Debug = true) - MySQL 5.7+ 默认开启
ONLY_FULL_GROUP_BY,用Raw写聚合 + JOIN 时,SELECT 字段必须都在 GROUP BY 里,否则报错Expression #1 of SELECT list is not in GROUP BY clause
真正要用好左连接,得先看清需求边界:关系明确就靠 RelatedSel;条件灵活或跨域关联,就得亲手写 Raw 并自己管好连接和事务。











