Gorm 关联查询预加载 Preloading

默认情况下 Gorm 因为性能问题,不会自动加载关联属性的值,Gorm 通过 Preload 函数支持预加载(Eager loading)关联数据,下面介绍预加载关联数据的方法。

 

1. 预加载范例

// 用户表
type User struct {
  gorm.Model
  Username string
  Orders []Orders // 关联订单,一对多关联关系
}
// 订单表
type Orders struct {
  gorm.Model
  UserID uint // 外键字段 
  Price float64
}

// 预加载Orders字段值,Orders字段是User的关联字段
db.Preload("Orders").Find(&users)
// 下面是自动生成的SQL,自动完成关联查询
// SELECT * FROM users;
// SELECT * FROM orders WHERE user_id IN (1,2,3,4);


// Preload第2,3个参数支持设置SQL语句条件和绑定参数
db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
// 自动生成的SQL如下
// SELECT * FROM users;
// SELECT * FROM orders WHERE user_id IN (1,2,3,4) AND state NOT IN ('cancelled');

// 通过组合Where函数一起设置SQL条件
db.Where("state = ?", "active").Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
// 自动生成的SQL如下
// SELECT * FROM users WHERE state = 'active';
// SELECT * FROM orders WHERE user_id IN (1,2) AND state NOT IN ('cancelled');

// 预加载Orders、Profile、Role多个关联属性
// ps: 预加载字段,必须是User的属性
db.Preload("Orders").Preload("Profile").Preload("Role").Find(&users)
// SELECT * FROM users;
// SELECT * FROM orders WHERE user_id IN (1,2,3,4); // has many
// SELECT * FROM profiles WHERE user_id IN (1,2,3,4); // has one
// SELECT * FROM roles WHERE id IN (4,5,6); // belongs to

 

2. 自动预加载

type User struct {
  gorm.Model
  Name       string
  CompanyID  uint
  Company    Company `gorm:"PRELOAD:false"` // 通过标签属性关闭预加载
  Role       Role                           // 默认开启预加载特性
}
// 通过Set设置gorm:auto_preload属性,开启自动预加载,查询的时候才会自动完成关联查询
db.Set("gorm:auto_preload", true).Find(&users)

 

3. 嵌套预加载

// 预加载User.Orders.OrderItems属性值,使用点连接嵌套属性即可
db.Preload("Orders.OrderItems").Find(&users)
db.Preload("Orders", "state = ?", "paid").Preload("Orders.OrderItems").Find(&users)

Gorm框架 自动建表(Migration特性):Gorm 支持 Migration 特性,支持根据 Go Struct 结构自动生成对应的表结构。Gorm 的 AutoMigrate 函数,仅支持建表,不支持修改字段和删除字段,避免意外导致丢失数据。通过 AutoMigrate 函数可以快速建表,如果表已经存在不会重复创建。