gorm 關係 has one 有一個

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

建立記錄

一塊兒建立 User 和 CreditCard

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 各個字段被填上正確的值。

分別建立 User 和 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)
相關文章
相關標籤/搜索