You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:51:04