如何在Golang Bun ORM中让Bulletin结构体直接关联Channel集合?
问题:Bun ORM实现Bulletin与Channel的直接多对多关联
我目前使用Uptrace的Bun ORM访问数据库,ORM关联功能运行良好,但在实现三级关联时遇到困难。现有结构体定义如下:
type Channel struct { ID int `json:"id" bun:",pk,autoincrement"` Value string `json:"value"` } type Bulletin struct { ID int `json:"id" bun:",pk,autoincrement"` Body string `json:"body"` } type BulletinChannel struct { ID int `json:"id" bun:",pk,autoincrement"` BulletinID int `json:"-"` ChannelID int `json:"-"` }
我已实现Bulletin关联BulletinChannel,再由BulletinChannel关联Channel的结构,但这并非我想要的:
type Bulletin struct { ID int `json:"id" bun:",pk,autoincrement"` Body string `json:"body"` BulletinChannels []BulletinChannel `json:"channel" bun:"rel:has-many,join:id=bulletin_id"` } type BulletinChannel struct { ID int `json:"id" bun:",pk,autoincrement"` BulletinID int `json:"-"` ChannelID int `json:"-"` Channel *Channel `json:"channel" bun:"belongs-to,join:id=user_i"` }
我希望直接在Bulletin结构体中拥有Channel实例集合,如下所示,请问是否可行?若可行,bun标签应如何填写?
type Bulletin struct { ID int `json:"id" bun:",pk,autoincrement"` Body string `json:"body"` Channels []Channel `json:"channel" bun:"rel:has-many,????"` //what to add here???? }
解决方案
完全可行,这是Bun ORM支持的多对多直接关联,无需通过中间结构体多层嵌套。你只需要在Channels字段的bun标签中明确多对多关联规则、中间表信息以及字段映射关系即可。
修正后的Bulletin结构体如下:
type Bulletin struct { ID int `json:"id" bun:",pk,autoincrement"` Body string `json:"body"` Channels []Channel `json:"channels" bun:"rel:many-to-many,join:id=bulletin_id,join:channel_id=id,join_table:bulletin_channels"` }
标签参数说明:
rel:many-to-many:声明该字段是多对多关联类型join:id=bulletin_id:指定当前Bulletin结构体的ID字段,对应中间表bulletin_channels的bulletin_id字段join:channel_id=id:指定关联的Channel结构体的ID字段,对应中间表的channel_id字段join_table:bulletin_channels:显式指定多对多关联的中间表名称(需与数据库中实际表名一致,若表名是Bun默认生成的蛇形命名,可省略此参数,但显式指定更清晰)
查询示例
要预加载Bulletin关联的Channels,只需在查询时调用Relation("Channels"):
var bulletins []Bulletin err := db.NewSelect().Model(&bulletins).Relation("Channels").Scan(ctx) if err != nil { // 处理错误逻辑 }
注:中间表bulletin_channels在数据库中必须存在对应的结构,若不需要在代码中显式操作中间表,可无需保留BulletinChannel结构体。
内容的提问来源于stack exchange,提问作者Apin
相关产品推荐
相关产品推荐

