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)
相关文章
相关标签/搜索