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

Golang Bun ORM带额外属性的多对多关系及属性访问方法

访问Go Bun多对多中间表的额外字段

当多对多关联的中间表(如OrderToItem)包含额外字段(如CreatedAt)时,无法再通过直接关联目标模型(如Item)的方式获取中间表数据,需要调整模型结构,将中间表作为关联的直接载体:

1. 修改模型定义

把Order结构体中的Items字段类型改为中间表OrderToItem的切片,这样就能直接访问中间表的所有字段:

func init() {
    db.RegisterModel((*OrderToItem)(nil))
}

type Order struct {
    ID    int64           `bun:",pk"`
    // 改为关联中间表,而非直接关联Item
    Items []*OrderToItem `bun:"rel:has-many,join:id=order_id"`
}

type Item struct {
    ID int64 `bun:",pk"`
}

type OrderToItem struct {
    OrderID   int64     `bun:",pk"`
    Order     *Order    `bun:"rel:belongs-to,join:order_id=id"`
    ItemID    int64     `bun:",pk"`
    Item      *Item     `bun:"rel:belongs-to,join:item_id=id"`
    CreatedAt time.Time `bun:",nullzero"` // 标签处理空时间值
}

2. 查询并访问字段

查询订单时,通过预加载关联的Item,就能同时获取中间表的CreatedAt和关联的商品数据:

// 查询指定订单,预加载中间表及关联商品
var order Order
err := db.NewSelect().Model(&order).
    Where("id = ?", targetOrderID).
    Relation("Items").          // 加载中间表数据
    Relation("Items.Item").    // 加载关联的Item实例
    Scan(ctx)
if err != nil {
    // 处理错误逻辑
}

// 遍历访问中间表字段和关联商品
for _, orderItem := range order.Items {
    fmt.Printf("商品ID: %d, 关联创建时间: %v\n", orderItem.Item.ID, orderItem.CreatedAt)
}

补充说明

  • 如果需要保留原有直接获取Item切片的能力,可以在Order中新增字段(如RawItems []Item),但这种方式无法同时获取中间表的附加数据,仅适用于不需要额外字段的场景。
  • 初始化时仍需注册中间表模型,确保Bun能正确识别关联关系。

内容的提问来源于stack exchange,提问作者Jan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 01:23:17