gorm 预加载的使用场景

发布时间: 2020-07-10 18:17:15 作者: 大象笔记

背景

我正在用 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"`
}

参考

我是一名山东烟台的开发者,联系作者