教程 > gorm 教程 > 阅读:166

gorm 预加载——迹忆客-ag捕鱼王app官网

预加载示例

gorm允许使用 preload 通过多个sql中来直接加载关系, 例如:

type user struct {
  gorm.model
  username string
  orders   []order
}
type order struct {
  gorm.model
  userid uint
  price  float64
}
// 查找 user 时预加载相关 order
db.preload("orders").find(&users)
// select * from users;
// select * from orders where user_id in (1,2,3,4);
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

joins 预加载

preload 在一个单独查询中加载关联数据。而 join preload 会使用 left join 加载关联数据,例如:

db.joins("company").joins("manager").joins("account").first(&user, 1)
db.joins("company").joins("manager").joins("account").first(&user, "users.name = ?", "jinzhu")
db.joins("company").joins("manager").joins("account").find(&users, "users.id in ?", []int{1,2,3,4,5})

带条件的 join

db.joins("company", db.where(&company{alive: true})).find(&users)
// select `users`.`id`,`users`.`name`,`users`.`age`,`company`.`id` as `company__id`,`company`.`name` as `company__name` from `users` left join `companies` as `company` on `users`.`company_id` = `company`.`id` and `company`.`alive` = true;

注意 join preload 适用于一对一的关系,例如: has one , belongs to


预加载全部

与创建、更新时使用 select 类似,clause.associations 也可以和 preload 一起使用,它可以用来 预加载 全部关联,例如:

type user struct {
  gorm.model
  name       string
  companyid  uint
  company    company
  role       role
  orders     []order
}
db.preload(clause.associations).find(&users)

clause.associations 不会预加载嵌套的关联关系,但是你可以将其与嵌套预加载一起使用, 例如:

db.preload("orders.orderitems.product").preload(clause.associations).find(&users)

条件预加载

gorm 允许带条件的 preload 关联,类似于内联条件

// 带条件的预加载 order
db.preload("orders", "state not in (?)", "cancelled").find(&users)
// select * from users;
// select * from orders where user_id in (1,2,3,4) and state not in ('cancelled');
db.where("state = ?", "active").preload("orders", "state not in (?)", "cancelled").find(&users)
// select * from users where state = 'active';
// select * from orders where user_id in (1,2) and state not in ('cancelled');

自定义预加载 sql

我们可以通过 func(db *gorm.db) *gorm.db 实现自定义预加载 sql,例如:

db.preload("orders", func(db *gorm.db) *gorm.db {
  return db.order("orders.amount desc")
}).find(&users)
// select * from users;
// select * from orders where user_id in (1,2,3,4) order by orders.amount desc;

嵌套预加载

gorm 支持嵌套预加载,例如:

db.preload("orders.orderitems.product").preload("creditcard").find(&users)
// 自定义预加载 `orders` 的条件
// 这样,gorm 就不会加载不匹配的 order 记录
db.preload("orders", "state = ?", "paid").preload("orders.orderitems").find(&users)

查看笔记

扫码一下
查看教程更方便
网站地图