一、概述
HasMany
与另一个模型建立一对多的连接,拥有者可以拥有零个或多个关联模型。
二、模型建立
依旧以User
和CreditCard
为例,一个User
可以拥有多张CreditCard
。HasMany
关系模型的实现主要在拥有者模型中定义。
1. 拥有者模型
-
实现
HasMany
模型,拥有者需要拥有以下字段:(1) 外键:默认为被拥有者的主键,在被拥有者模型中定义,在被拥有者模型切片变量中标注。
(2) 引用:默认为拥有者的主键,在拥有者模型中定义,在被拥有者模型切片变量中标注。
(3) 被拥有者模型切片变量;
-
以下是拥有者模型
User
的定义:以
CreditCard
模型中的UserID
作为外键,以ID
作为索引(默认)。type User struct { ID uint `gorm:"primary_key"` Name string Password string `gorm:"<-;->:false"` CreditCards []CreditCard `gorm:"foreignKey:UserID;references:ID"` }
2. 被拥有者模型(关联模型)
-
实现
HasMany
模型,被拥有者按照正常的逻辑定义,必要时可以添加拥有者模型的外键,如上User
模型中使用CreditCard
模型中的UserID
变量作为外键。 -
与上
User
对应的CreditCard
模型如下:type CreditCard struct { ID uint `gorm:"primary_key"` UserID uint `gorm:"->:false;<-"` Number string }
三、相关操作
1. 创建
- 定义完整的实例对象,调用
Save
方法保存。
func TestSaveUser() {
user := User{
Name: "Jason",
Password: "123",
CreditCards: []CreditCard{
{Number: "1234567890"},
{Number: "0987654321"},
},
}
err := SaveUser(user)
if err != nil {
log.Println("用户保存失败!")
} else {
log.Println("用户保存成功!")
}
}
func SaveUser(user User) error {
var err error
err = db.Save(&user).Error
return err
}
2. 查询
- 需要加载关联模型,使用
Preload
方法。
func GetUserByName(name string) (User, error) {
var user User
var err error
err = db.Where("name = ?", name).Preload("CreditCards").First(&user).Error
return user, err
}
3. 添加关联模型实例
- 向已有的记录添加关联模型实例,如向已有的
User
记录添加CreditCard
记录。
func AppendCardByUser(user User, card CreditCard) error {
var err error
err = db.Model(&user).Association("CreditCards").Append(&card)
return err
}
其中Association
方法的参数为要添加的关联模型类型,对应关联模型的切片变量名。