gpt4 book ai didi

orm - Gorm Golang orm 关联

转载 作者:IT老高 更新时间:2023-10-28 13:01:00 25 4
gpt4 key购买 nike

我将 Go 与 GORM ORM 一起使用.我有以下结构。关系很简单。一个城镇有多个地方,一个地方属于一个城镇。

type Place struct {
ID int
Name string
Town Town
}

type Town struct {
ID int
Name string
}

现在我想查询所有地方,并与他们的所有字段一起获取相应城镇的信息。这是我的代码:

db, _ := gorm.Open("sqlite3", "./data.db")
defer db.Close()

places := []Place{}
db.Find(&places)
fmt.Println(places)

我的示例数据库有这些数据:

/* places table */
id name town_id
1 Place1 1
2 Place2 1

/* towns Table */
id name
1 Town1
2 Town2

收到这个:

[{1 Place1 {0 }} {2 Mares Place2 {0 }}]

但我期待收到这样的东西(两个地方属于同一个城镇):

[{1 Place1 {1 Town1}} {2 Mares Place2 {1 Town1}}]

我怎样才能做这样的查询?我尝试使用 PreloadsRelated 没有成功(可能是错误的方式)。我无法获得预期的结果。

最佳答案

TownID 必须指定为外键。 Place 结构是这样的:

type Place struct {
ID int
Name string
Description string
TownID int
Town Town
}

现在有不同的方法来处理这个问题。例如:

places := []Place{}
db.Find(&places)
for i, _ := range places {
db.Model(places[i]).Related(&places[i].Town)
}

这肯定会产生预期的结果,但请注意日志输出和触发的查询。

[4.76ms]  SELECT  * FROM "places"
[1.00ms] SELECT * FROM "towns" WHERE ("id" = '1')
[0.73ms] SELECT * FROM "towns" WHERE ("id" = '1')

[{1 Place1 {1 Town1} 1} {2 Place2 {1 Town1} 1}]

输出是预期的,但是这种方法有一个根本缺陷,请注意,对于每个地方都需要进行另一个数据库查询,这会产生 n + 1 问题。这可以解决问题,但随着场所数量的增加,很快就会失控。

事实证明,方法使用预加载相当简单。

db.Preload("Town").Find(&places)

就是这样,产生的查询日志是:

[22.24ms]  SELECT  * FROM "places"
[0.92ms] SELECT * FROM "towns" WHERE ("id" in ('1'))

[{1 Place1 {1 Town1} 1} {2 Place2 {1 Town1} 1}]

这种方法只会触发两个查询,一个针对所有地点,一个针对所有有地点的城镇。这种方法适用于地点和城镇的数量(在所有情况下只有两个查询)。

关于orm - Gorm Golang orm 关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29435783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com