美文网首页
GORM many2many关系表的创建和查询

GORM many2many关系表的创建和查询

作者: _敏讷 | 来源:发表于2020-03-27 19:22 被阅读0次

    最近在用golang搭建个人博客的后台,数据库选用了gorm + mySQL的组合,其中文章(articles)和标签(tags)两个表是多对多的关系,由于对数据库不是很熟悉,外加gorm的文档较为简略,在这里踩了很多的坑。现在在这篇文章中总结下实现的方法。

    第一步:定义gorm表的struct

    type Article struct {
        gorm.Model
        Title     string            `gorm:"not null"`
        Content   string    `gorm:"not null"`
        Tags      []Tag     `gorm:"many2many:tag_articles"`
    }
    
    type Tag struct {
        TagId       string      `gorm:"primary_key"`
        TagName   string        `gorm:"unique;not null"`
        Articles  []Article     `gorm:"many2many:tag_articles"`
    }
    

    第二步:连接数据库,创建表

    func InitDB() *gorm.DB {
        //创建一个数据库的连接
        var err error
        db, err := gorm.Open("mysql","root:071918@tcp(127.0.0.1:3306)/blog?charset=utf8")
        if err != nil {
            panic(err)
        }
    
        // 调用该语句会自动生成联结表tag_articles
        db.AutoMigrate(&Article{}, &Tag{})
        return db
    }
    

    第三步:存数据

    tag1 := Tag{ TagId: "001", TagName: "React" }
    db.Save(&tag1)
    article := Article{
        Title: "Redux进阶教程", 
            Content:   "正文内容",
            // 子项中的数据必须是保存过或者查找出的数据(即数据库已有的数据)
            Tags: []Tag {
            tag1,
        },
    }
    

    或者

    tagIdList := ["001", "002"]
    var tags []db.Tag
    // 分别查询tagIdList,并将结果插入tags列表
    for i := range tagIdList {
        tag := db.Tag{}
        DB.Where("tag_id = ?", tagIdList[i]).First(&tag)
        tags = append(tags, tag)
    }
    
    articleModel := db.Article{
        Title:  "这是标题",
        Content:  "这是正文",
        Tags:      tags,
    }
    // 保存
    err := DB.Save(&articleModel)
    

    在上述步骤中有需要注意的是,Tags对应的数组项必须事先存入数据库,或者事先查找过,否则仅会生成article的记录,不会生成tag_articles联结表的记录。

    第四步:查询

    因为不熟悉gorm的API,有一部分查询是使用基本的sql语句查询的,性能方面可能不太好,但是作为个人博客后端使用问题不大。

    查询带标签(Tag)子项的文章(Article)列表

    var articleList []Article
    err := DB.Preload("Tags").Find(&articleList)
    fmt.Println(articleList)
    

    查询带文章数(Count)的标签(Tag)列表

    // 定义所需的struct
    type tagResult struct {
        Count int
        TagName string
        TagId   string
    }
    var tagList []tagResult
    err := DB.Raw("SELECT COUNT(*) count, t.tag_name, t.tag_id " +
        // 下面这句使用笛卡尔积连接两个表,复杂度变成了m * n,性能较差
        "FROM tag_articles ta, tags t " +
        "WHERE t.tag_id=ta.tag_tag_id " +
        "GROUP BY ta.tag_tag_id ").Scan(&tagList)
    fmt.Println(tagList)
    

    根据标签(TagId)查询全部文章列表

    // 定义所需的struct
    type articleResult struct {
        Title     string
        ArticleId string
    }
    var articleList []articleResult
    tagId := "001"
    // 查询语句
    err := DB.Raw("SELECT a.title, a.article_id "+
            // 下面这句使用笛卡尔积连接两个表,复杂度变成了m * n,性能较差
        "FROM tag_articles ta, articles a "+
        "WHERE a.article_id=ta.article_article_id "+
        "AND ta.tag_tag_id= ? ", tagId).Scan(&articleList)
    fmt.Println(articleList)
    

    相关文章

      网友评论

          本文标题:GORM many2many关系表的创建和查询

          本文链接:https://www.haomeiwen.com/subject/jhhruhtx.html