一对一 关联建立了与另一个模型的一对一连接,但语义(和结果)略有不同。此关联表示模型的每个实例都包含或拥有另一个模型的一个实例。
例如,如果您的应用程序包含用户和信用卡,并且每个用户只能拥有一张信用卡。
type User struct { gorm.Model CreditCard CreditCard }
type CreditCard struct { gorm.Model Number string UserID uint }
|
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"` }
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"}})
|
您可以使用标签 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"}})
|
请查看 关联模式 以了解如何使用 一对一 关系
GORM 允许使用 Preload 或 Joins 预加载 一对一 关联,有关详细信息,请参阅 预加载(渴望加载)
type User struct { gorm.Model Name string ManagerID *uint Manager *User }
|
您可以使用标签 constraint 设置 OnUpdate、OnDelete 约束,它将在使用 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 删除