gorm 多对多关系 以及 关联的操作
gorm多对多关系 以及 关联的操作前言多对多关系模型创建关联的操作不用预加载使用预加载查找关联添加关联删除关联替换关联清空关联前言关联的操作最重要的是many2many关系的维护多对多关系模型创建Many to Many 会在两个 model 中添加一张连接表。type GirlGOD struct {gorm.ModelName stringDogs []Dog `gorm:"many2man
·
前言
关联的操作最重要的是many2many关系的维护
多对多关系模型创建
Many to Many 会在两个 model 中添加一张连接表。
type GirlGOD struct {
gorm.Model
Name string
Dogs []Dog `gorm:"many2many:dog_girl_tables"`
}
type Dog struct {
gorm.Model
Name string
GirlGODs []GirlGOD `gorm:"many2many:dog_girl_tables"`
Info Info
}
type Info struct {
gorm.Model
Age int
Money int
DogID uint
}
func main() {
db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{})
db.AutoMigrate(&GirlGOD{}, &Dog{}, &Info{})
}
现在设置成dog1号舔狗舔2个女神,创建dog1的时候,会自动将其关联的girl,info,第三张中间表插入信息
func main() {
db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{})
db.AutoMigrate(&GirlGOD{}, &Dog{}, &Info{})
g1 := GirlGOD{
Name: "girl1",
}
g2 := GirlGOD{
Name: "girl2",
}
info1 := Info{Money: 20000}
d1 := Dog{
Name: "dog1",
GirlGODs: []GirlGOD{g1, g2},
Info: info1,
}
db.Debug().Create(&d1)
}
2022/05/15 23:33:54 C:/Users/68725/Desktop/leetcode/main.go:42
[0.672ms] [rows:1] INSERT INTO `infos` (`created_at`,`updated_at`,`deleted_at`,`age`,`money`,`dog_id`) VALUES ('2022-05-15 23:33:54.308','2022-05-15 23:33:54.308',NULL,0,20000,1) ON DUPLICATE KEY UPDATE `dog_id`=VALUES(`dog_id`)
2022/05/15 23:33:54 C:/Users/68725/Desktop/leetcode/main.go:42
[0.593ms] [rows:2] INSERT INTO `girl_gods` (`created_at`,`updated_at`,`deleted_at`,`name`) VALUES ('2022-05-15 23:33:54.309','2022-05-15 23:33:54.309',NULL,'girl1'),('2022-05-15 23:33:54.309','2022-05-15 23:33:54.309',NULL,'girl2') ON DUPLICATE KEY UPDATE `id`=`id`
2022/05/15 23:33:54 C:/Users/68725/Desktop/leetcode/main.go:42
[0.516ms] [rows:2] INSERT INTO `dog_girl_tables` (`dog_id`,`girl_god_id`) VALUES (1,1),(1,2) ON DUPLICATE KEY UPDATE `dog_id`=`dog_id`
2022/05/15 23:33:54 C:/Users/68725/Desktop/leetcode/main.go:42
[43.094ms] [rows:1] INSERT INTO `dogs` (`created_at`,`updated_at`,`deleted_at`,`name`) VALUES ('2022-05-15 23:33:54.269','2022-05-15 23:33:54.269',NULL,'dog1')
再创建一个舔狗2号,舔1,2号女神。现在的关系是
func main() {
db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{})
db.AutoMigrate(&GirlGOD{}, &Dog{}, &Info{})
g1 := GirlGOD{
Model: gorm.Model{ID: 1},
Name: "girl1",
}
g2 := GirlGOD{
Model: gorm.Model{ID: 2},
Name: "girl2",
}
info2 := Info{Money: 200}
d2 := Dog{
Name: "dog1",
GirlGODs: []GirlGOD{g1, g2},
Info: info2,
}
db.Debug().Create(&d2)
}
关联的操作
不用预加载
不用预加载可以发现只查询到了dog的信息,女神信息和info信息都没查出来
func main() {
db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{})
db.AutoMigrate(&GirlGOD{}, &Dog{}, &Info{})
d := Dog{
Model: gorm.Model{ID: 1},
}
db.Debug().Find(&d)
fmt.Println(d)
}
2022/05/15 23:43:25 C:/Users/68725/Desktop/leetcode/main.go:34
[39.958ms] [rows:1] SELECT * FROM `dogs` WHERE `dogs`.`deleted_at` IS NULL AND `dogs`.`id` = 1
{{1 2022-05-15 23:39:58.732 +0800 CST 2022-05-15 23:39:58.732 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} dog1 [] {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} 0 0 0}}
使用预加载
使用Preload发现会自动的从中间表中去加载女神信息
func main() {
db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{})
db.AutoMigrate(&GirlGOD{}, &Dog{}, &Info{})
d := Dog{
Model: gorm.Model{ID: 1},
}
db.Debug().Preload("GirlGODs").Find(&d)
fmt.Println(d)
}
2022/05/15 23:45:07 C:/Users/68725/Desktop/leetcode/main.go:34
[2.252ms] [rows:2] SELECT * FROM `dog_girl_tables` WHERE `dog_girl_tables`.`dog_id` = 1
2022/05/15 23:45:07 C:/Users/68725/Desktop/leetcode/main.go:34
[0.517ms] [rows:2] SELECT * FROM `girl_gods` WHERE `girl_gods`.`id` IN (1,2) AND `girl_gods`.`deleted_at` IS NULL
2022/05/15 23:45:07 C:/Users/68725/Desktop/leetcode/main.go:34
[44.198ms] [rows:1] SELECT * FROM `dogs` WHERE `dogs`.`deleted_at` IS NULL AND `dogs`.`id` = 1
{{1 2022-05-15 23:39:58.732 +0800 CST 2022-05-15 23:39:58.732 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} dog1 [{{1 2022-05-15 23:39:58.782 +0800 CST 2022-05-15 23:39:58.782 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} girl1 []} {{2 2022-05-15 23:39:58.782 +0800 CST 2022-05-15 23:39:58.782 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} girl2 []}] {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} 0 0 0}}
查找关联
只想通过舔狗查出女神,但是不想要舔狗的信息
func main() {
db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{})
db.AutoMigrate(&GirlGOD{}, &Dog{}, &Info{})
d := Dog{
Model: gorm.Model{ID: 1},
}
var gs []GirlGOD
db.Debug().Model(&d).Association("GirlGODs").Find(&gs)
fmt.Println(gs)
}
[38.528ms] [rows:2] SELECT `girl_gods`.`id`,`girl_gods`.`created_at`,`girl_gods`.`updated_at`,`girl_gods`.`deleted_at`,`girl_gods`.`name` FROM `girl_gods` JOIN `dog_girl_tables` ON `dog_girl_tables`.`girl_god_id` = `girl_gods`.`id` AND `dog_girl_tables`.`dog_id` = 1 WHERE `girl_gods`.`deleted_at` IS NULL
[{{1 2022-05-15 23:39:58.782 +0800 CST 2022-05-15 23:39:58.782 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} girl1 []} {{2 2022-05-15 23:39:58.782 +0800 CST 2022-05-15 23:39:58.782 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} girl2 []}]
func main() {
db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{})
db.AutoMigrate(&GirlGOD{}, &Dog{}, &Info{})
d := Dog{
Model: gorm.Model{ID: 1},
}
var gs []GirlGOD
db.Debug().Model(&d).Preload("Dogs").Association("GirlGODs").Find(&gs)
fmt.Println(gs)
}
只想通过舔狗查出女神,但是不想要舔狗的信息,但是又想要女神的舔狗的信息,这里Preload还可以后面跟条件,或者joins
2022/05/15 23:50:15 C:/Users/68725/Desktop/leetcode/main.go:35
[0.515ms] [rows:4] SELECT `dog_girl_tables`.`girl_god_id`,`dog_girl_tables`.`dog_id` FROM `dog_girl_tables` WHERE `dog_girl_tables`.`girl_god_id` IN (1,2)
2022/05/15 23:50:15 C:/Users/68725/Desktop/leetcode/main.go:35
[0.000ms] [rows:2] SELECT `dogs`.`id`,`dogs`.`created_at`,`dogs`.`updated_at`,`dogs`.`deleted_at`,`dogs`.`name` FROM `dogs` WHERE `dogs`.`id` IN (1,2) AND `dogs`.`deleted_at` IS NULL
2022/05/15 23:50:15 C:/Users/68725/Desktop/leetcode/main.go:35
[41.313ms] [rows:2] SELECT `girl_gods`.`id`,`girl_gods`.`created_at`,`girl_gods`.`updated_at`,`girl_gods`.`deleted_at`,`girl_gods`.`name` FROM `girl_gods` JOIN `dog_girl_tables` ON `dog_girl_tables`.`girl_god_id` = `girl_gods`.`id` AND `dog_girl_tables`.`dog_id` = 1 WHERE `girl_gods`.`deleted_at` IS NULL
[{{1 2022-05-15 23:39:58.782 +0800 CST 2022-05-15 23:39:58.782 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} girl1 [{{1 2022-05-15 23:39:58.732 +0800 CST 2022-05-15 23:39:58.732 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} dog1 [] {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} 0 0 0}} {{2 2022-05-15 23:40:52.887 +0800 CST 2022-05-15 23:40:52.887 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} dog1 [] {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} 0 0 0}}]} {{2 2022-05-15 23:39:58.782 +0800 CST 2022-05-15 23:39:58.782 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} girl2 [{{1 2022-05-15 23:39:58.732 +0800 CST 2022-05-15 23:39:58.732 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} dog1 [] {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} 0 0 0}} {{2 2022-05-15 23:40:52.887 +0800 CST 2022-05-15 23:40:52.887 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} dog1 [] {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} 0 0 0}}]}]
添加关联
跟dog3添加两个关联,发现中间表被自动维护了
func main() {
db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{})
db.AutoMigrate(&GirlGOD{}, &Dog{}, &Info{})
d3 := Dog{
Name: "dog3",
}
g1 := GirlGOD{Model: gorm.Model{ID: 1}}
g2 := GirlGOD{Model: gorm.Model{ID: 2}}
db.Create(&d3)
db.Model(&d3).Association("GirlGODs").Append(&g1, &g2)
}
删除关联
func main() {
db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{})
db.AutoMigrate(&GirlGOD{}, &Dog{}, &Info{})
d3 := Dog{
Model: gorm.Model{ID: 3},
}
g2 := GirlGOD{Model: gorm.Model{ID: 2}}
db.Debug().Model(&d3).Association("GirlGODs").Delete(&g2)
}
替换关联
替换关联会把当前所有的关系进行替换
func main() {
db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{})
db.AutoMigrate(&GirlGOD{}, &Dog{}, &Info{})
d3 := Dog{
Model: gorm.Model{ID: 3},
}
g2 := GirlGOD{Model: gorm.Model{ID: 2}}
db.Debug().Model(&d3).Association("GirlGODs").Replace(&g2)
}
g1 := GirlGOD{Model: gorm.Model{ID: 1}}
g2 := GirlGOD{Model: gorm.Model{ID: 2}}
db.Debug().Model(&d3).Association("GirlGODs").Replace(&g1, &g2)
清空关联
db.Debug().Model(&d3).Association("GirlGODs").Clear()
//[2.550ms] [rows:2] DELETE FROM `dog_girl_tables` WHERE `dog_girl_tables`.`dog_id` = 3

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)