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

Har*_*wal 6 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)

Run Code Online (Sandbox Code Playgroud)

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

preload是用来缓存结果的吗?

maj*_*rif 11

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

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

db.Preload("Username")
Run Code Online (Sandbox Code Playgroud)

另一方面,以下几点:

db.Preload("Orders").Find(&users)
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

type User struct {
  gorm.Model
  Username string
  Orders []Order
}
Run Code Online (Sandbox Code Playgroud)

当您users像这样填充切片时:

db.Find(&users)
//// SELECT * FROM users;
Run Code Online (Sandbox Code Playgroud)

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

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

db.Preload("Orders").Find(&users)
Run Code Online (Sandbox Code Playgroud)

user.Orders会通过用户的命令来填充。这是一种使处理关系更容易的抽象。

丑陋的选择是:

db.Find(&users)

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

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

如果您的用户有帖子、评论和订单,那么您可以像这样定义和查询它:

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

db.Preload("Orders").Preload("Comments").Preload("Posts").Find(&users)
Run Code Online (Sandbox Code Playgroud)

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

我希望这有帮助。

  • 您应该删除“您只需实际阅读页面上的信息”的声明。您的解释正是为什么首先需要这篇文章。Gorm 文档缺乏更简单的解释。我会将其标记为“向上”,因为这是一个很好的解释,除了第一个声明:) (17认同)