为了账号安全,请及时绑定邮箱和手机立即绑定

关系数据库导致循环

关系数据库导致循环

Go
守着星空守着你 2022-11-28 17:00:28
我有以下层次结构,用户 -> 地图 -> 元素 -> 帖子 一个用户可以有一堆地图,每个地图都有一些元素,每个元素都有一些帖子。输入用户结构{UserID        uint   `gorm:"primarykey;autoIncrement;not_null"`UserName string `json: user_name`FirstName string `json: first_name`LastName  string `json: last_name`Email     string `json:email`Password  []byte `json:"-"`Phone     string `json:"phone"`Maps []Map `gorm:"-"`}类型地图结构{MapID   uint      `gorm:"primarykey;autoIncrement;not_null"`UserID   uint    `json:userid`User     User      `json:"user"; gorm:"foreignkey:UserID`Title    string    `json:title`Desc     string    `json: "desc"`Elements []Element `gorm:"foreignKey:MapID"`Date     time.Time `json: date`}类型元素结构{ElementID   uint       `gorm:"primarykey;autoIncrement;not_null"`ElementName string     `json: element_name`Desc        string     `json: desc`MapID uint `json:mapid`Map   Map   `json:"map"; gorm:"foreignkey:MapID`Posts       []Post     `gorm:"foreignKey:ElementID"`Date        time.Time  `json: date`UserID uint `json:userid`User   User   `json:"user"; gorm:"foreignkey:UserID`}输入 Post 结构 {PostId    uint      `gorm:"primarykey;autoIncrement;not_null"`Title     string    `json: p_title`Subject   string    `json: subject`Date      time.Time `json: date`Entry     string    `json: entry_text`ElementID uint `json:elementid`Element   Element   `json:"element"; gorm:"foreignkey:ElementID`UserID uint `json:userid`User   User   `json:"user"; gorm:"foreignkey:UserID`}这一切似乎工作正常,但现在当我从后端发送 JSON 响应时,似乎有可能出现无限循环。当我检索所有用户的地图时,它会列出与创建地图的用户相关的用户对象,但地图随后还包含一个元素列表,并且在元素对象中它将列出它所属的地图和该地图对象将再次列出它的所有元素。那么我应该通过在一个方向上预加载层次结构来处理这个问题吗?var getmaps []models.Map database.DB.Preload("User").Preload("Map").Preload("Elements").Offset(偏移).Limit(限制).Find(&getmaps)或者我应该修复 struct 和 gorm 设置以仅在一个方向上获得关系?因为返回一个地图将返回它的元素,每个元素将返回它所属的地图,循环回到它的元素等。这个循环也会发生在元素和帖子中,其中一个元素将有很多帖子,这些帖子对象将显示其元素,而该元素对象将显示其帖子。我确信有一种理想或最佳的方式来实现这一点,所以只是好奇人们会推荐什么。
查看完整描述

1 回答

?
白板的微信

TA贡献1883条经验 获得超3个赞

在您的Post,Map和Element结构中,您具有以下字段:


UserID uint   `json:userid`

User   User   `json:"user"; gorm:"foreignkey:UserID`

您应该User从内容结构中删除该字段,因为您已经有一个UserID. 在这种情况下,“引用”(ID) 比包括整个用户对象更明智。如果需要,客户端可以调用/users/{id}端点并查找更多信息。


还User通过删除限制结构的内容Maps []Map(负责您提到的循环)。然后您需要设置端点,/user/{id}/maps以便客户端可以获取用户的内容。


这同样适用于Post和Element。您可以全力以赴只存储 ID,也可以只存储一组“子”模型。(地图嵌入元素,元素不嵌入地图)。因此,要查找元素的关联映射,您可以调用 endpoint /maps/{your element's map ID}。Element > Post 相同


type Map struct {

    gorm.Model // this takes care of the ID field

    UserID   uint    `json:userid`

    Title    string    `json:title`

    Desc     string    `json: "desc"`

    Elements []Element // gorm will handle the relationship automatically

    Date     time.Time `json: date`

}

type Element struct {

gorm.Model // includes ID

ElementName string     `json: element_name`

Desc        string     `json: desc`

MapID uint `json:mapid`

// Map   Map  ... This relationship is described by another endpoint - /elements/{elementId}/map to get the related map


Posts       []Post     // gorm handles this

Date        time.Time  `json: date`

UserID uint `json:userid`

}

type Post struct {

    gorm.Model

    Title     string    `json: p_title`

    Subject   string    `json: subject`

    Date      time.Time `json: date`

    Entry     string    `json: entry_text`

    ElementID uint `json:elementid` // gorm will use this as fk

    UserID uint `json:userid`

}

为避免循环,您需要在结构级别使关系成为单向的,并设置更多的 http 路由以朝另一个方向发展(请参阅注释代码)。


我描述的是一个简单的 REST api。微软有一个很好的概述:https ://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design#organize-the-api-design-around-resources - 特别是客户/订单关系你会感兴趣的。


在 gorm 方面,您将使用一对多关联:https ://gorm.io/docs/has_many.html


查看完整回答
反对 回复 2022-11-28
  • 1 回答
  • 0 关注
  • 57 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信