预加载功能在gorm中有什么作用?

时间:2019-12-24 16:43:34

标签: go go-gorm

链接http://gorm.io/docs/preload.html讨论了GORM中的预加载,但我无法理解此功能的作用。

type User struct {
  gorm.Model
  Username string
  Orders Order
}
type Order struct {
  gorm.Model
  UserID uint
  Price float64
}


db.Preload("Username")

db.Preload("Orders").Find(&users)

有人可以解释这两个语句的作用吗?输出是什么?

是否使用preload来缓存结果?

1 个答案:

答案 0 :(得分:0)

您提供的链接显示了它的作用。您只需要实际阅读页面上的信息即可。

首先,这实际上没有任何作用:

db.Preload("Username")

另一方面,以下内容:

db.Preload("Orders").Find(&users)

做某事。首先填充users,然后填充[]user.Orders。在您链接的页面上的评论中,您会找到它,它通过查询显示了它的作用:

db.Preload("Orders").Find(&users)
//// SELECT * FROM users;
//// SELECT * FROM orders WHERE user_id IN (1,2,3,4);

那这到底是做什么的?我可以给您提供技术答案,您可以通过搜索急切加载轻松找到,或者可以通过示例来给您答案,我觉得这很简单。

所以让我以示例的方式进行解释。

说您有用户,每个用户可以有多个订单。这是一对多关系,可以这样定义:

type User struct {
  gorm.Model
  Username string
  Orders []Order
}

当您填充users切片时,如下所示:

db.Find(&users)
//// SELECT * FROM users;

如果您需要获得每个用户的所有订单,则可以轻松访问user.Orders,但是由于它没有被填充,因此无论如何都是空的。

如果我们像这样填充users切片:

db.Preload("Orders").Find(&users)

user.Orders将由该用户的订单填充。这是使关系处理变得更容易的抽象。

丑陋的选择是:

db.Find(&users)

for user := range users {
  db.Where("user_id", user.id).Find(&user.Orders)
}

它还会向数据库发出更多不必要的请求。 (不好)

如果您的用户有“帖子,评论和订单”,则可以这样定义和查询:

type User struct {
  gorm.Model
  Username string
  Orders []Order
  Comments []Comment
  Posts []Post
}

db.Preload("Orders").Preload("Comments").Preload("Posts").Find(&users)

仅需上面的代码,您现在就可以访问数据库中不同表中的用户数据。

我希望有帮助。