gorm preload 限制 field 字段

发布时间: 2023-05-22 16:53:11 作者: 大象笔记

例如,我想用 golang gorm 查询订单表中关联的代理商名称,但是用 Gorm Preload 又会将代理商信息中多余的敏感信息取出来, 例如联系人等信息。于是就需要限制 Preload 的返回字段。

Models

type Order struct {
	gorm.Model
	AgentId       int            // 代理商 id
	Agent         Agent          // 代理商信息
	Status        int
}

type Agent struct {
	gorm.Model
	Name      string  // 代理商名称
	UserName  string  // 负责人姓名。敏感信息,不想返回
	Tel       string  // 负责人电话。敏感信息,不想返回
}

正确的做法

var items []models.Order
db := models.DB.
	Preload("Agent", func(tx *gorm.DB) *gorm.DB {
		return tx.Select("ID", "Name")
	})
	db.Where("status = 1").
		Order("id desc").
		Find(&items)

注意,即便只查询 Name 字段,也需要将 ID 字段一并加上。

错误的做法

var items []models.Order
db := models.DB.
	Preload("Agent", func(tx *gorm.DB) *gorm.DB {
		return tx.Select("Name")
	})
	db.Where("status = 1").
		Order("id desc").
		Find(&items)

不加 ID 就会报警告信息:

failed to assign association &models.Agent

注意,只是警告,但不报错。

这是我非常不喜欢 Gorm 的一点,很多场景下只报警告,不报错误异常。无法暴露问题。

Gorm 替代品

我有点想尝试类似 SQLDelight 的 golang 实现:

https://github.com/kyleconroy/sqlc

Gorm 这种 ORM 里面坑太多,远不如直接写 SQL 安全,高效,排查问题也简单。

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