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
相关产品推荐
相关产品推荐

