Belongs To
将一个模型与另一个模型建立一对一的关系
例如:一张银行卡只能分配给一个用户,在User
结构体里面创建一个CreditCardId
外键关系,然后在User
结构体里面嵌套一个CreditCard
结构体
// Belongs To
// 用户
type User struct {
gorm.Model
CreditCardId int64
CreditCard CreditCard
}
// 银行卡
type CreditCard struct {
gorm.Model
Number string
}
根据结构体创建对应的表结构
db.AutoMigrate(&User{})
users表:
credit_cards表:
插入一条数据
user := User{
CreditCardId: 100,
CreditCard: CreditCard{
Number: "123456",
},
}
db.Create(&user)
users表:
credit_cards表:
根据id查询一条数据
需要使用预加载,否则嵌套结构体里面的内容将不会被查询出来
var user User
err = db.Preload("CreditCard").Where("id=?", 1).Find(&user).Error
if err != nil {
fmt.Printf("err: %v\n", err)
}
fmt.Printf("user: %v\n", user)
注意:在对表进行删除的时候应该先删除父表(users表),再删除子表(credit_cards)
Has One
同样的,Has One
也是用来建立一对一的关系,这种关联表明一个模型的每个实例都包含或拥有另一个模型的一个实例。与Belongs To
不同的是,外键的位置是在嵌套结构体的内部
// Has One
// 用户
type User struct {
gorm.Model
CreditCard CreditCard
}
//银行卡
type CreditCard struct {
gorm.Model
Number string
UserID int64
}
根据结构体创建对应表结构
db.AutoMigrate(&User{}, &CreditCard{})
users表:
credit_cards表
插入一条数据
关于结构体的内容,属性是gorm.model的内容时不必进行赋值,由于CreditCard
属于内部嵌套结构体,所以UserID
无需指定,值是User结构体的ID值
user := User{
CreditCard: CreditCard{
Number: "100",
},
}
db.Create(&user)
users表
credit_cards表
查询数据仍然需要使用预加载
var user User
err = db.Preload("CreditCard").Where("id=?", 1).Find(&user).Error
if err != nil {
fmt.Printf("err: %v\n", err)
}
fmt.Printf("user: %v\n", user)
Has Many
Has Many
将一个模型与另一个模型建立一对多的关系,嵌套结构体是一个切片类型,而在嵌套内部结构体将通过一个id保证与外部结构体的关系
银行卡的例子说明,每一个人可以拥有很多张银行卡,但是每张银行卡都有对应属于自己的id值
// Has Many
type User struct {
gorm.Model
CreditCard []CreditCard
}
type CreditCard struct {
gorm.Model
Number string
UserID int64
}
根据结构体创建对应表结构
建表的时候与Has One
键的表一样
db.AutoMigrate(&User{}, &CreditCard{})
插入一条数据
user := User{
CreditCard: []CreditCard{
{Number: "100"}, {Number: "101"}, {Number: "101"},
},
}
db.Create(&user)
对应users表,创建一个一个用户,对用credit_cards表,将创建三条银行卡数据
查询数据需要使用预加载
var user User
err = db.Preload("CreditCard").Where("id=?", 1).Find(&user).Error
if err != nil {
fmt.Printf("err: %v\n", err)
}
fmt.Printf("user: %v\n", user)
Many To Many
Many to Many
会在两个 model 中添加一张连接表
例如:在一个大小合适中的关系网中,一个人可以有多个群聊,每个群聊都有多个不同的人。
// Many To Many
type User struct {
gorm.Model
ChatGroups []ChatGroup `gorm:"many2many;"`
}
type ChatGroup struct {
gorm.Model
Name string
}
根据结构体创建对应表结构
db.AutoMigrate(&User{})
使用User结构体将创建三个表users
表,chat_groups
表,user_chat_group
表
插入一条数据
var user = User{
ChatGroups: []ChatGroup{
{Name: "幸福一家人"}, {Name: "研究生小分队"}, {Name: "钓鱼佬永不空军"},
},
}
db.Create(&user)
对于第一次插入数据,没有指定的id将被自动赋值,默认升序,第二次插入数据:新建一个用户id=2,用户的群聊是id等于1,2的两个群聊
var user = User{
Model: gorm.Model{
ID: 2,
},
ChatGroups: []*ChatGroup{
{
Model: gorm.Model{
ID: 1,
},
},
{
Model: gorm.Model{
ID: 2,
},
},
},
}
db.Create(&user)
此时,users表中添加一条数据,chat_groups表中没有新数据插入,user_chat_group对应关系表中插入两条数据
查询数据
var chats []ChatGroup
//查询指定群聊,并且预加载群聊里面的人
db.Preload("User").Where("id=?", 1).Find(&chats).Association("ChatGroup")
fmt.Printf("chats: %v\n", chats)