扫码一下
查看教程更方便
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
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');
我们可以通过 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)