英文:
Gorm get all data from table with condition on nested table
问题
我有一个包含Golang结构体的表格,如下所示:
type Order struct {
ID int
TransactionID int
Transaction Transaction
}
type Transaction struct {
ID int
ProfileID int
Profile Profile
}
type Profile struct {
ID int
AccountID int
Account Account
}
如何使用gorm根据账户ID获取所有订单?我尝试了以下代码,但它没有起作用:
var orders []*Order
res := r.db.
Joins("Transaction").
Preload("Transaction.Profile").
Where("Transaction.Profile.account_id = 1").
Find(&orders)
请注意,这只是一个示例代码,具体的解决方法可能因你的数据模型和数据库结构而异。你可能需要根据自己的情况进行调整。
英文:
I have a table with golang struct like this:
Order {
ID
TransactionID
Transaction
}
Transaction {
ID
ProfileID
Profile
}
Profile {
ID
AccountID
Account
}
How to get all the order with condition of account id with gorm?
I have tried this:
var orders []*Order
res := r.db.
Joins("Transaction").
Preload("Transaction.Profile").
Where("Transaction.Profile.account_id = 1").
Find(&orders)
But it does not work.
答案1
得分: 2
这个解决方案应该基于你提供的结构定义可以工作。首先,让我展示代码,然后逐步解释每个步骤:
package main
import (
"fmt"
_ "github.com/lib/pq"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type Order struct {
Id int
TransactionId int
Transaction Transaction
}
type Transaction struct {
Id int
ProfileId int
Profile Profile
}
type Profile struct {
Id int
AccountId int
Account Account
}
type Account struct {
Id int
}
func main() {
dsn := "host=localhost user=postgres password=postgres dbname=postgres port=5432 sslmode=disable"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
db.AutoMigrate(&Account{})
db.AutoMigrate(&Profile{})
db.AutoMigrate(&Transaction{})
db.AutoMigrate(&Order{})
db.Create(&Account{})
db.Create(&Profile{AccountId: 1})
db.Create(&Transaction{ProfileId: 1})
db.Create(&Order{TransactionId: 1})
// order + transaction + profile + account
var order Order
db.Debug().Preload("Transaction.Profile.Account").Joins("inner join transactions t on orders.transaction_id = t.id").Joins("inner join profiles p on p.id = t.profile_id").Joins("inner join accounts a on p.account_id = a.id").First(&order, "a.id = ?", 1)
fmt.Println(order)
}
让我们仔细看看代码。
结构定义
这部分没有改变。在声明结构时,请确保了解 GORM 的约定,因为 GORM 会根据此创建关系、外键和约束。
准备数据库
这里包括与 Postgres 的连接、自动迁移命令以同步表格,以及插入一些虚拟数据。
查询
在这里,我们使用了 GORM 包提供的许多方法。让我们在一个简短的列表中总结一下:
Debug
:它将原始 SQL 查询打印到控制台。在处理复杂查询时非常有用。Preload
:加载相关实体,但不将它们包含在 Gorm 生成的最终查询中。Joins
:指定在 JOIN 子句中引用哪些表。使用Joins
,我们向查询添加了 JOIN 子句。First
:用于仅获取一条记录,也用于指定一些过滤条件,例如我们的情况下的a.id = ?
。
如果这样解决了你的问题,请告诉我,谢谢!
英文:
This solution should work based on the structs definitions you provided. First, let me show the code and then I'll go through each step:
package main
import (
"fmt"
_ "github.com/lib/pq"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type Order struct {
Id int
TransactionId int
Transaction Transaction
}
type Transaction struct {
Id int
ProfileId int
Profile Profile
}
type Profile struct {
Id int
AccountId int
Account Account
}
type Account struct {
Id int
}
func main() {
dsn := "host=localhost user=postgres password=postgres dbname=postgres port=5432 sslmode=disable"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
db.AutoMigrate(&Account{})
db.AutoMigrate(&Profile{})
db.AutoMigrate(&Transaction{})
db.AutoMigrate(&Order{})
db.Create(&Account{})
db.Create(&Profile{AccountId: 1})
db.Create(&Transaction{ProfileId: 1})
db.Create(&Order{TransactionId: 1})
// order + transaction + profile + account
var order Order
db.Debug().Preload("Transaction.Profile.Account").Joins("inner join transactions t on orders.transaction_id = t.id").Joins("inner join profiles p on p.id = t.profile_id").Joins("inner join accounts a on p.account_id = a.id").First(&order, "a.id = ?", 1)
fmt.Println(order)
}
Let's take a closer look at the code.
Structs definitions
Nothing changed here. Be sure to know the GORM conventions when you declare the structs as GORM will create relations, foreign keys, and constraints based on this.
Preparing the database
Here, you can find the connection to Postgres, the auto-migrating commands to synchronize the tables, and the insert of some dummy data.
The query
Here, we used a lot of methods provided by the GORM package for Go. Let's recap them in a short list:
Debug
: it prints to the console the Raw SQL query. It's useful when dealing with complex queriesPreload
: loads the related entities but it doesn't include them in the final query produced by GormJoins
: it specifies which tables have to be referenced in a JOIN clause. With theJoins
we add the clause to the query.First
: it's used both for fetching only one record and also for specifying some filter such as in our case (e.g.a.id = ?
).
Let me know if this clarifies your issue, thanks!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论