gpt4 book ai didi

Gorm eager loading 加入多个关系

转载 作者:行者123 更新时间:2023-12-05 08:03:52 26 4
gpt4 key购买 nike

我有这样的数据设计:交易属于授权,而授权又属于客户。或者用结构体表示:

type Transaction struct { 
shared.Transaction // transaction data
MandateID string
Mandate *Mandate
}

type Mandate struct {
shared.Mandate // mandate data
ClientID string
Client *Client
Transactions []Transaction
}

type Client struct {
shared.Client // client data
Mandates []Mandate

}

我一直在尝试使用 joins preloading 预加载交易及其授权和客户数据。 .需要注意的是,此预加载仅适用于“拥有一个”或“属于”类型的关系。

如果我只需要交易和授权数据,这会很好地工作:

var trx []rdb.Transaction
err = t.db.
Joins("Mandate").
Find(&trx, "batch_id = ?", batchID).Error

但是,一旦我尝试同时加载客户端,gorm 就会生成无效的 SQL。代码:

var trx []rdb.Transaction
err = t.db.
Joins("Mandate").
Joins("Mandate.Client").
Find(&trx, "batch_id = ?", batchID).Error

我以前使用普通预加载,但是 Preload 启动的多个查询开始成为一个严重的性能问题。用 SQL 编写整个查询并扫描结果也是一种选择,但这首先违背了使用 ORM 的目的。

我如何使用 gorm 在单个查询中获取交易及其授权和客户数据?

最佳答案

要加载嵌套关联,例如 Mandate.Client,您需要使用 Preload 函数。

var trx []rdb.Transaction
err = t.db.
Preload("Mandate.Client").
Find(&trx, "batch_id = ?", batchID).Error

关于性能问题,是的,Preload 函数确实执行了多个查询。但是,如果您查看查询,您会发现它们已经尽可能地进行了优化。查询应如下所示:

SELECT * FROM clients WHERE id IN (23,43,12,3,2,73,121,1,9,21,39);

SELECT * FROM mandates WHERE id IN (1,2,3,4,5,6,21,43,54);

它确实扫描了整个表,但您可以看到它试图加载一组非常具体的数据。我不认为这个 ORM 能提供比这更多的帮助。事实是,如果您的批处理中有很多交易,并且您希望立即加载所有详细信息,那么您的性能会受到一些影响。

要提高您的方法的性能,您始终可以尝试通过使用 OffsetLimit 函数来引入分页以限制返回的事务数。或者,使用原始 SQL 查询返回非规范化结果并使用 for 循环和 Scan 读取行。

关于Gorm eager loading 加入多个关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71170220/

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