> 文章列表 > Gorm的关联模型

Gorm的关联模型

Gorm的关联模型

Belongs To

将一个模型与另一个模型建立一对一的关系

例如:一张银行卡只能分配给一个用户,在User结构体里面创建一个CreditCardId外键关系,然后在User结构体里面嵌套一个CreditCard结构体

// Belongs To
// 用户
type User struct {gorm.ModelCreditCardId int64CreditCard   CreditCard
}
// 银行卡
type CreditCard struct {gorm.ModelNumber string
}

根据结构体创建对应的表结构

db.AutoMigrate(&User{})

users表:
Gorm的关联模型
credit_cards表:
Gorm的关联模型

插入一条数据

user := User{CreditCardId: 100,CreditCard: CreditCard{Number: "123456",},
}
db.Create(&user)

users表:
Gorm的关联模型
credit_cards表:
Gorm的关联模型

根据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.ModelCreditCard CreditCard
}
//银行卡
type CreditCard struct {gorm.ModelNumber stringUserID int64
}

根据结构体创建对应表结构

db.AutoMigrate(&User{}, &CreditCard{})

users表:
Gorm的关联模型
credit_cards表
Gorm的关联模型

插入一条数据

关于结构体的内容,属性是gorm.model的内容时不必进行赋值,由于CreditCard属于内部嵌套结构体,所以UserID无需指定,值是User结构体的ID值

user := User{CreditCard: CreditCard{Number: "100",},
}
db.Create(&user)

users表
Gorm的关联模型
credit_cards表
Gorm的关联模型

查询数据仍然需要使用预加载

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.ModelCreditCard []CreditCard
}type CreditCard struct {gorm.ModelNumber stringUserID 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.ModelChatGroups []ChatGroup `gorm:"many2many;"`
}
type ChatGroup struct {gorm.ModelName string
}

根据结构体创建对应表结构

db.AutoMigrate(&User{})

使用User结构体将创建三个表users表,chat_groups表,user_chat_group

插入一条数据

var user = User{ChatGroups: []ChatGroup{{Name: "幸福一家人"}, {Name: "研究生小分队"}, {Name: "钓鱼佬永不空军"},},
}
db.Create(&user)

Gorm的关联模型
Gorm的关联模型
Gorm的关联模型

对于第一次插入数据,没有指定的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对应关系表中插入两条数据
Gorm的关联模型

查询数据

var chats []ChatGroup
//查询指定群聊,并且预加载群聊里面的人
db.Preload("User").Where("id=?", 1).Find(&chats).Association("ChatGroup")
fmt.Printf("chats: %v\\n", chats)