【GORM】模型关系-HasOne

一、概述
  • 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表字段描述

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
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值