一、概述
HasOne与另外一个模型建立一对一的关联,这种关联表明一个模型的每个实例都包含或拥有另一个模型实例。
二、模型建立
-
实现
HasOne模型,拥有者需要定义被拥有者的模型变量(关联模型变量),并在模型变量中指定:(1) 外键:在被拥有者模型中定义,在关联模型变量中标注。默认为
拥有者模型名ID,需要在关联模型中显式定义。(2) 引用:在拥有者模型中定义,类型要与外键变量的类型一致,在关联模型变量中标注,默认为关联模型的主键。
-
以用户
User拥有CreditCard为例,模型定义如下:(1)
CreditCard为关联模型变量,外键默认为CreditCard模型的UserID,引用为User模型的ID。// 拥有者模型。 type User struct { ID uint `gorm:"primary_key"` // 默认的引用 Password string `gorm:"->:false;<-"` CreditCard CreditCard // 关联模型变量。 } // 关联模型。 type CreditCard struct { ID uint `gorm:"primary_key"` UserID uint // 默认的外键,需要显式定义。 Number string `gorm:"type:varchar(20)"` }(2) 建表之后,在
CredictCard表中,会新增一个字段user_id,表示该CreditCard记录与之关联的User主键。User表字段描述

CreditCard表字段描述

三、重定义
1. 重定义外键
- 重定义外键,即在关联模型中指向引用的字段,需要在关联模型变量中标注。
- 如下重定义
UserRefer为外键,使用foreignKey标注关联模型变量CreditCard。
type User struct {
ID uint `gorm:"primary_key"`
Name string
Password string `gorm:"->:false;<-"`
CreditCard CreditCard `gorm:"foreignKey:UserRefer"`
}
type CreditCard struct {
ID uint `gorm:"primary_key"`
UserRefer uint
Number string `gorm:"type:varchar(20)"`
}
2. 重定义引用
- 重定义引用,即外键指向的标识,需要在关联模型变量中标注。
- 如下重定义
Name为引用。
type User struct {
ID uint `gorm:"primary_key"`
Name string
Password string `gorm:"->:false;<-"`
CreditCard CreditCard `gorm:"foreignKey:UserName;references:Name"`
}
type CreditCard struct {
ID uint `gorm:"primary_key"`
UserName string
Number string `gorm:"type:varchar(20)"`
}
四、相关操作
- 下列的操作基于以下的
HasOne关联模型
type User struct {
ID uint `gorm:"primary_key"`
Name string
Password string `gorm:"->:false;<-"`
CreditCard CreditCard `gorm:"foreignKey:UserName;references:Name"`
}
type CreditCard struct {
ID uint `gorm:"primary_key"`
UserName string
Number string `gorm:"type:varchar(20)"`
}
1. 保存
- 声明完整的结构体变量,调用
Save方法进行保存。
func TestSaveUser() {
user := User{
Name: "Jason",
Password: "12345",
CreditCard: CreditCard{
Number: "1234567890",
},
}
err := SaveUser(user)
if err != nil {
log.Println("用户保存失败!")
} else {
log.Println("用户保存成功!")
}
}
func SaveUser(user User) error {
err := db.Save(&user).Error
return err
}
2. 删除
- 删除实例有两种策略:
(1) 连同HasOne关联的对象记录删除,如上删除用户后连同账号记录一同删除。采用Select方法。如下,使用Select方法选择关联的模型,连同模型记录一同删除。
func DeleteUserByName(name string) error {
var user User
var err error
db.Model(&user).Where("name = ?", name).First(&user)
err = db.Model(&user).Select("CreditCard").Delete(&user).Error
return err
}
(2) 不删除关联的模型记录,与(1)类型,不使用Select方法。
3. 查询
-
在查询时需要加载关联模型,使用
Preload方法加载。func GetUserByName(name string) (User, error) { var user User err := db.Model(&user).Preload("CreditCard").Where("name = ?", name).First(&user).Error return user, err }
本文详细介绍了 GORM 中的 HasOne 关联,包括如何建立模型之间的一对一关联,如何重定义外键和引用,以及如何进行保存、删除和查询操作。通过 User 和 CreditCard 的例子,展示了如何在数据库中创建和管理关联关系。同时,讨论了在删除用户时是否删除关联的 CreditCard 记录的不同策略。
735

被折叠的 条评论
为什么被折叠?



