Gorm get all data from table with condition on nested table

huangapple go评论152阅读模式
英文:

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 queries
  • Preload: loads the related entities but it doesn't include them in the final query produced by Gorm
  • Joins: it specifies which tables have to be referenced in a JOIN clause. With the Joins 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!

huangapple
  • 本文由 发表于 2022年12月15日 16:56:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/74808999.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定