1. Has One

1.1. Has One

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

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

  1. // 用户有一个信用卡,CredtCardID 外键
  2. type User struct {
  3. gorm.Model
  4. CreditCard CreditCard
  5. }
  6. type CreditCard struct {
  7. gorm.Model
  8. Number string
  9. UserID uint
  10. }

1.2. 外键

对于一对一关系,一个外键字段也必须存在,所有者将保存主键到模型关联的字段里。

这个字段的名字通常由 belongs to model 的类型加上它的 primary key 产生的,就上面的例子而言,它就是 CreditCardID

当你给用户一个信用卡, 它将保存一个信用卡的 IDCreditCardID 字段中。

如果你想使用另一个字段来保存这个关系,你可以通过使用标签 foreignkey 来改变它, 例如:

  1. type User struct {
  2. gorm.Model
  3. CreditCard CreditCard `gorm:"foreignkey:CardRefer"`
  4. }
  5. type CreditCard struct {
  6. gorm.Model
  7. Number string
  8. UserName string
  9. }

1.3. 关联外键

通常,所有者会保存 belogns to model 的主键到外键,你可以改为保存其他字段, 就像下面的例子使用 Number

  1. type User struct {
  2. gorm.Model
  3. CreditCard CreditCard `gorm:"association_foreignkey:Number"`
  4. }
  5. type CreditCard struct {
  6. gorm.Model
  7. Number string
  8. UID string
  9. }

1.4. 多态关联

支持多态的一对多和一对一关联。

  1. type Cat struct {
  2. ID int
  3. Name string
  4. Toy Toy `gorm:"polymorphic:Owner;"`
  5. }
  6. type Dog struct {
  7. ID int
  8. Name string
  9. Toy Toy `gorm:"polymorphic:Owner;"`
  10. }
  11. type Toy struct {
  12. ID int
  13. Name string
  14. OwnerID int
  15. OwnerType string
  16. }

注意:多态属于和多对多是明确的不支持并将会抛出错误。

1.5. 使用一对一

你可以通过 Related 找到 has one 关联。

  1. var card CreditCard
  2. db.Model(&user).Related(&card, "CreditCard")
  3. //// SELECT * FROM credit_cards WHERE user_id = 123; // 123 是用户表的主键
  4. // CreditCard 是用户表的字段名,这意味着获取用户的信用卡关系并写入变量 card。
  5. // 像上面的例子,如果字段名和变量类型名一样,它就可以省略, 像:
  6. db.Model(&user).Related(&card)

更多高级用法,请参考 Association Mode