gorm 预加载的使用场景

更新日期: 2020-07-11 阅读次数: 1135 字数: 385 分类: golang

背景

我正在用 golang gin 写的一个统计人数小程序后台服务涉及两个大数据表

  • 用户表
  • 活动参与的用户表

在查询一个活动参与的所有用户信息时,需要同时用到这两个表。考虑到运营一段时间之后,这两个表的数据量不可控,所有不打算使用联表查询。而采用

  1. 先查询活动对应的用户 id 集合
  2. 然后 where in ids 来查询对应的用户信息

如果用 golang 手写这个逻辑,还挺啰嗦的。在翻看 gorm 文档时,发现 gorm 支持预加载功能,这个功能类似 laravel eloquent 里的 Eager Loading 功能 (相对于 lazy loading)。

预加载的使用方法

type WxActivityUser struct {
	Id         int         `json:"id"`
        ......
	User       UserProfile `json:"user"`
}

type UserProfile struct {
	Id       int    `json:"-"`
	Nickname string `json:"nickname"`
	Avatar   string `json:"avatar"`
}

db.Preload("User").Find(&activityUsers)

如何打印 gorm 语句对应的 SQL

想确认一下,orm 对应的 SQL 是否存在隐患。

db.LogMode(true)

这样就能在 gin 的日志输出中看到每条 sql 语句了。

可以避免联表查询?确实是我想要的效果。

[2020-07-09 21:07:24]  [3.37ms]  SELECT * FROM `wx_activity_user`  WHERE (activity_id = 3) ORDER BY id asc LIMIT 20
[10 rows affected or returned ]

[2020-07-09 21:07:24]  [3.26ms]  SELECT * FROM `wx_users`  WHERE (`id` IN (1))
[1 rows affected or returned ]

can't preload field

[2020-07-09 21:27:19] can't preload field User for models.WxActivityUser

需要在 Preload 的 model 里加上 Id。如果不想在输出为 json 格式时显示 id,只需要加上 json:"-"

type UserProfile struct {
	Id       int    `json:"-"`
	Nickname string `json:"nickname"`
	Avatar   string `json:"avatar"`
}

参考

  • https://gorm.io/zh_CN/docs/preload.html
  • https://learnku.com/articles/5581/optimizing-laravel-model-queries-with-preload
领取阿里云/腾讯云服务器优惠券

关于作者

我是来自山东烟台的一名开发者,喜欢瞎折腾,顺便记记笔记。有敢兴趣的话题,欢迎加微信 zhongwei 聊聊, 查看更多联系方式。 白天写程序,晚上哄熊孩子,可能回复有点慢,见谅。同时也欢迎关注我的微信公众号“大象工具”: 大象工具微信公众号

相关文章

爱评论不评论

近期节日

2020年10月22日 世界传统医药日
2020年10月23日 霜降
2020年10月24日 联合国日
2020年10月25日 重阳节
2020年10月31日 世界勤俭日
2020年11月01日 万圣节
2020年11月07日 立冬
2020年11月08日 中国记者日
2020年11月10日 世界青年节
2020年11月11日 光棍节
2020年11月14日 世界糖尿病日
2020年11月17日 国际大学生节
查看更多节日