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

GORM中Has One与Belongs To的区别及适用场景解析

GORM中Has One与Belongs To的核心差异及适用场景

一、最本质的区别:外键存储位置

这是两者核心差异的根源,直接决定了关联关系的方向:

  • Has One:外键字段存储在关联的子模型中,当前模型是“拥有者”角色。
  • Belongs To:外键字段存储在当前模型中,当前模型是“从属者”角色。

二、关联关系与适用场景

1. Has One:“拥有”关系

适用于主模型唯一对应一个子模型的场景,典型例子:

  • 用户拥有唯一的个人档案
  • 订单拥有唯一的物流跟踪信息
  • 手机拥有唯一的电池组件

代码示例:

// User 主模型(拥有者)
type User struct {
  gorm.Model
  Name    string
  Profile Profile // 声明Has One关联
}

// Profile 子模型(被拥有者),外键UserID存储在此
type Profile struct {
  gorm.Model
  UserID uint   // 外键,关联User表的ID字段
  Bio    string
  Avatar string
}

GORM会自动识别UserID为外键关联User的ID。查询时可通过主模型加载关联数据:

var user User
// 预加载Profile关联数据
db.Preload("Profile").First(&user, "id = ?", 1)

2. Belongs To:“属于”关系

适用于当前模型从属某个主模型的场景,是Has One的反向关联,典型例子:

  • 个人档案属于某个用户
  • 物流信息属于某个订单
  • 电池组件属于某台手机

代码示例:

// Profile 从属模型,外键UserID存储在此
type Profile struct {
  gorm.Model
  UserID uint   // 外键,关联User的ID
  Bio    string
  User   User   // 声明Belongs To关联
}

// User 主模型
type User struct {
  gorm.Model
  Name string
}

查询从属模型时,可加载其所属的主模型:

var profile Profile
// 预加载所属的User数据
db.Preload("User").First(&profile, "id = ?", 1)

三、常见注意事项

  • 不要混淆关联逻辑:比如用户作为拥有者,外键绝不能放在User模型里关联档案,这违背“拥有”的逻辑。
  • 自定义外键时,Has One需在关联字段上指定子模型的外键;Belongs To需指定当前模型的外键和主模型的关联字段,示例:
// 自定义Has One外键
type User struct {
  gorm.Model
  Name      string
  Profile   Profile `gorm:"foreignKey:OwnerID"` // 指定子模型外键为OwnerID
}

type Profile struct {
  gorm.Model
  OwnerID uint // 自定义外键
  Bio     string
}

// 自定义Belongs To外键
type Profile struct {
  gorm.Model
  OwnerID uint   // 当前模型外键
  Bio     string
  User    User   `gorm:"foreignKey:OwnerID;references:ID"` // 指定外键与主模型关联字段
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:24:25