【问题标题】:Golang Gorm reverse hasMany relationGolang Gorm 反向 hasMany 关系
【发布时间】:2020-02-13 03:54:15
【问题描述】:

我们可以通过 Preload 在 Golang Gorm 中轻松获取 hasMany 关系的子节点。 但是如何获得反向关系。

type Owner struct {
    ID         int        `gorm:"column:id" json:"id"`
    Name       string     `gorm:"column:name" json:"name"`
    Projects   []Project  `gorm:"foreignkey:OwnerID" json:"projects"`
}

type Project struct {
    ID          int     `gorm:"column:id" json:"id"`
    Name        string  `gorm:"column:name" json:"name"`
    OwnerID     int     `gorm:"column:owner_id" json:"owner_id"`
    Gallery     []Gallery `gorm:"foreignkey:ProjectID" json:"gallery"`
}

type Gallery struct {
    ID             int    `gorm:"column:id" json:"id"`
    ProjectID      int    `gorm:"column:project_id" json:"project_id"`
    Url            string `gorm:"column:url" json:"url"`
    Title          string `gorm:"column:title" json:"title"`
    Description    string `gorm:"column:description" json:"description"`
}

我们可以使用 Preload 在 Project 中填充 Gallery,如下所示:

db.Preload("Gallery").Find(&project)

如何获得反向,我们想从画廊或项目的所有者加载项目?

当以 json 形式获取项目时,我想要这样的结果:

{
   "id": 1,
   "name": "Name Of Project",
   "owner": {
      "id":1,
      "name": "Owner 1"
   },
   "gallery":[]
}

【问题讨论】:

  • 我也在找这个。我来自 NodeJS(express),它有办法做到这一点。有人吗?

标签: go go-gorm


【解决方案1】:

我对这个答案有点晚了,但是您可以通过这样做在子模型上定义反向关系(属于):

type ParentModel struct {
    Children []Child // This is a 'has many'
}

type Child struct {
    ParentModelID int // These behave as a 'belongs to'
    ParentModel ParentModel // You need both the model and the modelID
}

完整的工作示例

这将使用您问题中的模型。关于性能的说明,gorm 中的预加载不是通过连接完成的。它是通过额外的 SQL 查询完成的,嵌套越多查询越多。如果您经常执行预加载,则可能值得编写原始查询和客户扫描程序以使用优化查询。

package main

import (
    "fmt"
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

type Owner struct {
    gorm.Model
    Projects []Project
}

type Project struct {
    gorm.Model
    OwnerID int
    Owner   Owner
    Gallery []Gallery
}

type Gallery struct {
    gorm.Model
    ProjectID int
    Project   Project
}

func main() {
    db, err := gorm.Open(sqlite.Open("many2many.db"), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    err = db.AutoMigrate(&Owner{}, &Project{}, &Gallery{})
    if err != nil {
        return
    }

    ownerOne := Owner{}
    db.Create(&ownerOne)

    projectOne := Project{Owner: ownerOne}
    projectTwo := Project{Owner: ownerOne}
    db.Create(&projectOne)
    db.Create(&projectTwo)

    galleryOne := Gallery{Project: projectOne}
    galleryTwo := Gallery{Project: projectOne}

    galleryThree := Gallery{Project: projectTwo}
    galleryFour := Gallery{Project: projectTwo}

    db.Create(&galleryOne)
    db.Create(&galleryTwo)
    db.Create(&galleryThree)
    db.Create(&galleryFour)

    // Find by project and preload owners
    fetchedProject := Project{}
    db.Preload("Owner").Find(&fetchedProject, projectOne.ID)
    fmt.Println(fetchedProject.Owner)

    // Find by a gallery and preload project and owner
    fetchedGallery := Gallery{}
    db.Preload("Project.Owner").Find(&fetchedGallery, galleryOne.ID)
    fmt.Printf("Gallery.id = %d --> Project.id = %d --> Owner.id = %d\n", fetchedGallery.ID,
        fetchedGallery.Project.ID, fetchedGallery.Project.Owner.ID)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多