在Gorm中结合2个或更多模型生成结构结果的最佳方法是什么?
给定这些示例模型:
type Book struct {
gorm.Model
Title string
Description string
AuthorID uint
}
type Author struct {
gorm.Model
FirstName string
LastName string
Books []Book
}
我想创建一个查询,通过标题
查找图书db.Where("title=?", "foo").Find(&books)
到目前为止没有问题,但我还想包括Author。姓名和作者。结果中的LastName。这对我尝试的任何方法都不起作用,因为Book结构不包括这些字段。期望的结果应该包括匹配Book中的所有字段加上与该Book相关的Author中的所有字段。
尝试使用Select()和Join()函数指定所需的所有字段,从而生成正确的SQL语句,但结果Book结构仍然不包含任何Author字段。
我可以通过这种方式完成您的请求。
首先,我将Author Author
字段添加到Book
结构体。通过这种方式,你可以保存作者的信息和他的书。
在查询中,您必须使用Preload("Auhtor")
来让GORM也从authors
表加载信息。这种做法被称为急切加载。下面,你可以找到我的工作解决方案:
package main
import (
"fmt"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type Book struct {
gorm.Model
Title string
Description string
AuthorID uint
Author Author
}
type Author struct {
gorm.Model
FirstName string
LastName string
Books []Book
}
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(&Book{})
db.AutoMigrate(&Author{})
book1 := &Book{Title: "Go", Description: "Intro to Golang", AuthorID: 1}
book2 := &Book{Title: "GORM", Description: "Intro to GORM", AuthorID: 1}
author := &Author{FirstName: "John", LastName: "Doe", Books: []Book{*book1, *book2}}
db.Create(author)
var books []Book
db.Preload("Author").Where("title=?", "Go").Find(&books)
for _, v := range books {
fmt.Println("book 1:")
fmt.Printf("title: %qnn", v.Title)
fmt.Printf("author details:n")
fmt.Printf("first name: %qn", v.Author.FirstName)
fmt.Printf("last name: %qn", v.Author.LastName)
}
}
希望这能帮助你理解
请看下面的例子,看看我们如何在Gorm中生成一个包含两个或多个模型的结构体。
type Driver struct {
gorm.Model
Name string
License string
Cars []Car
}
type Car struct {
gorm.Model
Year int
Make string
ModelName string
DriverID int
}
var (
drivers = []Driver{
{Name: "Shashank", License: "India123"},
{Name: "Tom", License: "India321"},
}
cars = []Car{
{Year: 2000, Make: "Toyota", ModelName: "Tundra", DriverID: 1},
{Year: 2001, Make: "Honda", ModelName: "Accord", DriverID: 1},
}
)
func GetCars(w http.ResponseWriter, r *http.Request) {
var cars []Car
db.Find(&cars)
json.NewEncoder(w).Encode(&cars)
}
// Getting cars with the id, where it will include name of driver & license
func GetCar(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
var car Car
db.First(&car, params["id"])
json.NewEncoder(w).Encode(&car)
}
请注意这不是完整的代码,它基本上是你的完整代码的解决方案的参考,你可以检查我的仓库。https://github.com/amshashankk/GO_Postgres_Testing/blob/main/main.go