有一個(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)