【问题标题】:What does Preload function do in gorm?gorm中的Preload函数有什么作用?
【发布时间】:2023-03-11 02:06:01
【问题描述】:

链接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用来缓存结果吗?

【问题讨论】:

  • 我不是来自 Go 生态系统。我对 Java 生态系统中的这个术语很熟悉。我会说,这是为了性能问题。有两个术语。急切加载和延迟加载。延迟加载意味着相关实体不会被加载,直到我们需要它们。急切加载是对一种实体类型的查询同时加载相关实体作为查询的一部分的过程。它使用更多的内存。但其他调用的计算量较少。希望清楚。

标签: go go-gorm


【解决方案1】:

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

首先,这并没有真正做任何事情:

db.Preload("Username")

另一方面,如下:

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

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

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

那么这到底有什么作用呢?我可以给你技术答案,你可以通过谷歌搜索 eager loading 轻松找到它,或者我可以通过例子给你一个我觉得更简单的答案。

所以让我通过例子来解释一下。

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

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)

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

希望对你有帮助。

【讨论】:

  • 我有一个问题。例如,如果 orders 表里面有另一个嵌套表,你如何预加载它?我应该像其他人一样用同样的方式链接它吗?这是db.Preload("Orders").Preload("TableInsideOrders").Find(&users) 正确吗?
  • @arahpanah 不正确 - 在 Preload 的 gorm 文档中,您将看到以下 db.Preload("Orders.OrderItems").Find(&users)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 2015-10-08
  • 2012-10-14
相关资源
最近更新 更多