gorm 多对多关系 以及 关联的操作

前言

关联的操作最重要的是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
  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cheems~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值