ORM框架Gorm-Many To Many

ORM框架Gorm-Many To Many,第1张

多对多关联 定义博客标签结构体
// 博客文章
type Blog struct {
	gorm.Model
	Name    string
	Content string `gorm:"type:text"`
	Tags    []Tag  `gorm:"many2many:blog_tags"`
}

// 标签结构体
type Tag struct {
	gorm.Model
	Name string
	Blog []Blog `gorm:"many2many:blog_tags"`
}
连接数据库并初始化数据库
var db *gorm.DB

func init() {
	dsn := "root:root@tcp(127.0.0.1:3306)/go_orm?charset=utf8mb4&parseTime=True&loc=Local"
	d, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal(err)
	}
	db = d
	db.AutoMigrate(&Blog{}, &Tag{})
}
添加模拟标签数据
// 创建测试标签
func CreateTags() {
	var tags = []Tag{
		{Name: "php"},
		{Name: "go"},
		{Name: "html"},
		{Name: "js"},
		{Name: "bootstrap"},
		{Name: "mysql"},
	}
	d := db.Create(tags)
	fmt.Printf("d.RowsAffected: %v\n", d.RowsAffected)
}
创建模拟博客数据
func CreateBlogTags() {
	var tags []Tag
	db.Model(&Tag{}).Find(&tags)
	for _, tag := range tags {
		fmt.Printf("tag.ID: %v--tag.Name: %v\n", tag.ID, tag.Name)
	}
	var blogs = []Blog{
		{Name: "blog1", Content: "blog1-blog2", Tags: []Tag{tags[0], tags[1]}},
		{Name: "blog2", Content: "blog2-blog2", Tags: []Tag{tags[2], tags[3], tags[4]}},
		{Name: "blog3", Content: "blog3-blog3", Tags: []Tag{tags[0], tags[2], tags[5]}},
	}
	d := db.Create(blogs)
	fmt.Printf("d.RowsAffected: %v\n", d.RowsAffected)
}
数据库表数据如下



预加载 查询所有博客并查询出对应下的标签
func testSelect1() {
	var blogs []Blog
	db.Preload("Tags").Find(&blogs)

	for _, blog := range blogs {
		fmt.Printf("blog.Name: %v\n", blog.Name)
		var tagsName []string
		for _, v := range blog.Tags {
			tagsName = append(tagsName, v.Name)
		}
		fmt.Printf("tagsName: %v\n", tagsName)
	}
	fmt.Println("----------------------------------------------")
}
查询所有标签并查询出对应的博客
func testSelect2() {
	var tags []Tag
	db.Preload("Blog").Find(&tags)
	for _, tag := range tags {
		fmt.Printf("tag.Name: %v\n", tag.Name)
		var blogsId []uint
		for _, v := range tag.Blog {
			blogsId = append(blogsId, v.ID)
		}
		fmt.Printf("blogsId: %v\n", blogsId)
	}
	fmt.Println("----------------------------------------------")
}

运行结果如下

嵌套预加载

查询所有博客以及博客下的标签,而且也要查到标签下面的所有博客,类似做相关性推荐

func testSelect3() {
	var blogs []Blog
	db.Preload("Tags.Blog").Find(&blogs)
	for _, blog := range blogs {
		fmt.Printf("blog.Name: %v\n", blog.Name)
		var tagsName []string
		for _, v := range blog.Tags {
			tagsName = append(tagsName, v.Name)
			var blogsId []uint
			for _, v1 := range v.Blog {
				blogsId = append(blogsId, v1.ID)
			}
			fmt.Printf("blogsId: %v\n", blogsId)

		}
		fmt.Printf("tagsName: %v\n", tagsName)
	}
	fmt.Println("----------------------------------------------")
}

添加关联

为博客在原有基础上添加新的标签

func addBlogTag() {
	var tags []Tag
	db.Model(&Tag{}).Find(&tags)
	var blog Blog
	db.Model(&Blog{}).Where("id", 1).Find(&blog)
	// 原来已有1 2标签
	db.Model(&blog).Association("Tags").Append([]Tag{tags[2], tags[3]})
}

运行结果后新增了3 4标签id,因为切片下标原因上面写的2,3

替换关联

把博客原有的标签替换为新的,相当于做博客更新

func replaceBLogTag() {
	var tags []Tag
	db.Model(&Tag{}).Find(&tags)
	var blog Blog
	db.Model(&Blog{}).Where("id", 1).Find(&blog)
	// 原来已有1 2 3 4标签
	db.Model(&blog).Association("Tags").Replace([]Tag{tags[4], tags[1]})

}

运行结果后只剩下2,5标签id

关联计数

查询具体博客有几个标签
查询具体标签有几个博客再用
查询所有标签分别有几个博客再用

func countBlogTag() {
	var blog Blog
	db.Model(&Blog{}).Where("id", 1).Find(&blog)
	i := db.Model(&blog).Association("Tags").Count()
	fmt.Printf("i: %v\n", i)
	fmt.Println("-----------------------------------------------")
}

func countTagBlog() {
	var tag Tag
	db.Model(&Tag{}).Where("id", 1).Find(&tag)
	i := db.Model(&tag).Association("Blog").Count()
	fmt.Printf("i: %v\n", i)
	fmt.Println("-----------------------------------------------")
}

func countAllTagBlog() {
	var tags []Tag
	db.Model(&Tag{}).Find(&tags)
	for _, tag := range tags {
		i := db.Model(&tag).Association("Blog").Count()
		fmt.Printf("tag.Name: %v--count:%v\n", tag.Name, i)
	}
}

运行结果如下

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/995763.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存