全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-21 8 分钟 ✍️ juanwangdev

GORM 关联查询与预加载

本文介绍 GORM 中关联查询的三种核心方式:延迟加载、Preload 预加载和 Joins 连接查询。

关联查询方式

延迟加载(Lazy Loading)

访问关联字段时才执行查询,容易产生 N+1 问题。

Go
// 查询用户
var user User
db.First(&user, 1)

// 访问关联 Profile 时触发额外查询
db.Model(&user).Association("Profile").Find(&user.Profile)

每条主记录产生一次额外查询,数据量大时性能急剧下降。

Preload 预加载

一次性加载所有关联数据,彻底解决 N+1 问题。

Go
// 预加载单一关联
db.Preload("Profile").First(&user, 1)

// 预加载多个关联
db.Preload("Profile").Preload("Orders").First(&user, 1)

// 嵌套预加载
db.Preload("Orders.Items").First(&user, 1)

// 条件预加载
db.Preload("Orders", "status = ?", "paid").First(&user, 1)

语法格式:

Go
db.Preload("关联字段名", "条件?", 参数...).Find(&results)

Joins 连接查询

使用 SQL JOIN 一次性获取关联数据,适合简单关联场景。

Go
// 内连接
db.Joins("JOIN profiles ON profiles.user_id = users.id").Find(&users)

// 带条件连接
db.Joins("JOIN orders ON orders.user_id = users.id AND orders.status = ?", "paid").Find(&users)

// 多个 Join
db.Joins("Profile").Joins("Company").Find(&users)

Joins 方式要求关联字段必须有外键关系,且不支持嵌套预加载。

Preload vs Joins 对比

特性PreloadJoins
查询方式多次查询(IN)单次 JOIN 查询
N+1 问题完全避免完全避免
嵌套关联支持不支持
性能数据量大时更优数据量小时更优
外键要求不要求数据库外键不要求数据库外键
适用场景复杂关联、嵌套加载简单关联、单次查询

注意事项

  1. 生产环境默认使用 Preload 解决 N+1 问题,而非延迟加载。
  2. 预加载条件中的参数使用位置参数,而非命名参数。
  3. Joins 方式返回的主记录可能包含重复数据,需配合 Group 或 Distinct 使用。

要点总结

  • 延迟加载简单但易产生 N+1 问题,仅适合少量数据场景。
  • Preload通过 IN 查询一次性加载关联数据,是解决 N+1 问题的首选方案。
  • Joins使用 SQL 连接查询,适合简单关联且数据量较小的场景。
  • 优先使用 Preload,复杂查询再考虑 Joins 或 Raw SQL。

存放路径:D:\git2\jwdev\articles\GORM\进阶\关联关系管理\关联查询与预加载.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 GORM 关联数据创建与更新
下一篇 → GORM 多对多关系配置
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库