一对一

一对一

一对一 关联建立了与另一个模型的一对一连接,但语义(和结果)略有不同。此关联表示模型的每个实例都包含或拥有另一个模型的一个实例。

例如,如果您的应用程序包含用户和信用卡,并且每个用户只能拥有一张信用卡。

声明

// User has one CreditCard, UserID is the foreign key
type User struct {
gorm.Model
CreditCard CreditCard
}

type CreditCard struct {
gorm.Model
Number string
UserID uint
}

检索

// Retrieve user list with eager loading credit card
func GetAll(db *gorm.DB) ([]User, error) {
var users []User
err := db.Model(&User{}).Preload("CreditCard").Find(&users).Error
return users, err
}

覆盖外键

对于 一对一 关系,还必须存在一个外键字段,拥有者会将其所属模型的主键保存到该字段中。

该字段的名称通常使用 一对一 模型的类型加上其 主键 生成,对于上面的示例,它是 UserID

当您向用户提供信用卡时,它会将用户的 ID 保存到其 UserID 字段中。

如果要使用其他字段保存关系,可以使用标签 foreignKey 更改它,例如

type User struct {
gorm.Model
CreditCard CreditCard `gorm:"foreignKey:UserName"`
// use UserName as foreign key
}

type CreditCard struct {
gorm.Model
Number string
UserName string
}

覆盖引用

默认情况下,被拥有实体会将 一对一 模型的主键保存到外键中,您可以更改为保存另一个字段的值,例如以下示例中使用 Name

您可以使用标签 references 更改它,例如

type User struct {
gorm.Model
Name string `gorm:"index"`
CreditCard CreditCard `gorm:"foreignKey:UserName;references:name"`
}

type CreditCard struct {
gorm.Model
Number string
UserName string
}

多态关联

GORM 支持 一对一一对多 的多态关联,它会将被拥有实体的表名保存到多态类型的字段中,将主键保存到多态字段中

type Cat struct {
ID int
Name string
Toy Toy `gorm:"polymorphic:Owner;"`
}

type Dog struct {
ID int
Name string
Toy Toy `gorm:"polymorphic:Owner;"`
}

type Toy struct {
ID int
Name string
OwnerID int
OwnerType string
}

db.Create(&Dog{Name: "dog1", Toy: Toy{Name: "toy1"}})
// INSERT INTO `dogs` (`name`) VALUES ("dog1")
// INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","dogs")

您可以使用标签 polymorphicValue 更改多态类型值,例如

type Dog struct {
ID int
Name string
Toy Toy `gorm:"polymorphic:Owner;polymorphicValue:master"`
}

type Toy struct {
ID int
Name string
OwnerID int
OwnerType string
}

db.Create(&Dog{Name: "dog1", Toy: Toy{Name: "toy1"}})
// INSERT INTO `dogs` (`name`) VALUES ("dog1")
// INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","master")

使用一对一进行 CRUD 操作

请查看 关联模式 以了解如何使用 一对一 关系

预加载

GORM 允许使用 PreloadJoins 预加载 一对一 关联,有关详细信息,请参阅 预加载(渴望加载)

自引用一对一

type User struct {
gorm.Model
Name string
ManagerID *uint
Manager *User
}

外键约束

您可以使用标签 constraint 设置 OnUpdateOnDelete 约束,它将在使用 GORM 迁移时创建,例如

type User struct {
gorm.Model
CreditCard CreditCard `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
}

type CreditCard struct {
gorm.Model
Number string
UserID uint
}

您还可以在删除时使用 Select 删除选定的一对一关联,有关详细信息,请查看 使用 Select 删除

铂金赞助商

黄金赞助商

铂金赞助商

黄金赞助商