有一个(has one)关联也创建了与另外一个模型的一对一链接,但有一些不一样的语义(和后果)。此关联表示模型的每一个实例包含或拥有另外一个模型的一个实例。sql
例如,若是您的应用程序包括用户和信用卡以及每一个用户 只能有一张信用卡。ui
定义模型:code
// User has one CreditCard, UserID is the foreign key // User 有一个 CreditCard,UserId 是外键 type CreditCard struct { gorm.Model Number string UserID uint } type User struct { gorm.Model CreditCard CreditCard }
credit_cards 表的 user_id 列是外键,它引用 users 表的 id 列。orm
has one 关系和 belongs to 关系实际上是一会事,全部者有一个附属者,附属者属于一个全部者,User 有一个 CreditCard,CreditCard 属于一个 User。ci
区别在于定义模型时,has one 关系,把附属者 CreditCard 做为全部者 User 的一个字段,更天然;而 belongs to 关系,把全部者 User 做为附属者 CreditCard 的一个字段。string
对于 has one 关系,外键字段也必须存在,全部者将会保存它模型的主键到此外键中。这里是 users 的主键 id 将保存在 credit_cards 表的外键 user_id 中。it
外键字段名常常等于全部者的类型 + 全部者的主键,对于上面的示例,它是 User + ID = UserID。io
当你把一个 CreditCard 给那个 User,CreditCard 将会保存 User 的 ID 到它的 UserID 字段。class
若是你想要使用另外一字段保存这个关系,你能够用 tag foreignkey 来修改它,好比:变量
type CreditCard struct { gorm.Model Number string UserName string } type User struct { gorm.Model Name string CreditCard CreditCard `gorm:"foreignkey:UserName"` }
把 credit_cards 表的外键改为 user_name(默认为 user_id)。tag 须要写在全部者结构体的类型为从属者的字段上,这里是 User 的 CreditCard 字段。
关联外键指与外键有关联的键,被外键所引用的键。
默认,全部者实体将会保存模型的主键到外键,你能够更改以保存另外一个字段到外键,好比下面例子中改为了 Name 字段。
type CreditCard struct { gorm.Model Number string UID string } type User struct { gorm.Model Name `sql:"index"` CreditCard CreditCard `gorm:"foreignkey:uid;association_foreignkey:name"` }
外键改为 uid,关联外键改为 name。
u1 := &User{ Name: "swt", CreditCard: CreditCard{ Number: "110", }, } db.Create(u1)
当 u1 的 CreditCard 不为空时,db.Create(u1) 调用在 users 表建立 u1 记录后,又在 credit_cards 表中建立 u1.CreditCard 记录。以后 u1 及 u1.CreditCard 各个字段被填上正确的值。
u3 := &User{ Name: "swt", } db.Create(u3) u3.CreditCard.Number = "189" u3.CreditCard.UserID = u3.ID db.Create(&u3.CreditCard)
当 u3 的 CreditCard 为空时,db.Create(u3) 调用在 users 表建立 u3 记录后,不会在 credit_cards 表建立记录。
你能够用 Related 方法查找 has one 关系。
user := &User{} user.ID = 2 var card CreditCard db.Model(user).Related(&card, "CreditCard") //// SELECT * FROM credit_cards WHERE user_id = 2; // Related 方法第二个参数 "CreditCard" 是 user 的字段名, // 意味着获取 user 的 CreditCard 关系,而后填充到变量 card 中。 // 若是 CreditCard 的外键字段为 UserID, 则能省略第二个参数,自动查找关系,如 db.Model(user).Related(&card)