网站 架构设计,四年级的简短新闻播报,亳州做网站的公司,做网站关键词文章目录 多对多 many2many表结构搭建多对多添加多对多查询多对多的删除、更新 自定义连接表生成表结构操作案例添加文章并添加标签#xff0c;并自动关联添加文章#xff0c;关联已有标签给已有文章关联标签替换已有文章的标签查询文章列表#xff0c;显示标签 自定义连接… 文章目录 多对多 many2many表结构搭建多对多添加多对多查询多对多的删除、更新 自定义连接表生成表结构操作案例添加文章并添加标签并自动关联添加文章关联已有标签给已有文章关联标签替换已有文章的标签查询文章列表显示标签 自定义连接表主键操作连接表查询 多对多 many2many
Many to Many 会在两个 model 中添加一张连接表将不同表的id连接起来也就是说 总共三张表 我们这里以文章和其tag为例一篇文章可以有多个tag一个tag中也有多个文章
表结构搭建
type Article struct {ID uint gorm:size:8Title string gorm:size:16Tags []Tag gorm:many2many:article_tags; //用于确定多对多的关系并指定第三张连接表的名字
}
type Tag struct {ID uint gorm:size:8Text string gorm:size:16Articles []Article gorm:many2many:article_tags;//反向引用可以用来查询具有相同标签的文章
}DB.AutoMigrate(Article{}, Tag{})搭建表结构如图
多对多添加
创建标签和文章 建立一篇标题为“go”的文章并新建标签为study和language。
DB.Save(Article{ID: 1,Title: go,Tags: []Tag{{Text: language},{Text: study},},
})添加文章选择标签:这里以选择单个标签为例 如果不查询即使标签名字一致也会重建一个新的标签
var tag Tag
DB.Take(tag, Text?, study)
DB.Save(Article{Title: Study notes,Tags: []Tag{tag},
})多对多查询
//查询文章显示文章的标签列表
var article Article
DB.Preload(Tags).Take(article, 1)
fmt.Println(article)//查询标签显示具有该标签的文章列表
var tag Tag
DB.Preload(Articles).Take(tag, 2)
fmt.Println(tag)多对多的删除、更新
移除文章的标签
var article Article
DB.Preload(Tags).Take(article, 1)
DB.Model(article).Association(Tags).Delete(article.Tags)
fmt.Println(article)跟新文章的标签
article Article{}
var tags []TagDB.Find(tags, []int{1, 2, 3}) //找到想要添加的标签DB.Preload(Tags).Take(article, 1) //预加载要修改的文章DB.Model(article).Association(Tags).Replace(tags) //替换文章标签自定义连接表
默认的连接表只有双方的主键id展示不了更多信息了为了
type Article struct {ID uintTitle stringTags []Tag gorm:many2many:article2tag;
}type Tag struct {ID uintText string//Articles []Article gorm:many2many:article2tag; //当使用反向引用时需要在setUpJoinTable时多设置一次这个表的
}// Article2tag 自定义连接表
type Article2tag struct {ArticleID uint gorm:primaryKeyTagID uint gorm:primaryKey //上两项即为连接表默认项CreatedAt time.Time //自定义添加一个创建时间字段
}生成表结构
//第一个参数为具有连接另一个表的字段的连接表第二个即为连接字段的字段名第三个为连接表
DB.SetupJoinTable(Article{}, Tags, Article2tag{})
//DB.SetupJoinTable(Tag{}, Articles, Article2tag{}) //与上面反向引用时对应
DB.AutoMigrate(Article{}, Tag{}, Article2tag{})操作案例 我们如果在自定义连接表中设置了默认字段之外的字段的话需要使用添加钩子beforeCreate来赋值,这里的createAt字段gorm会自动填充关于钩子函数 SetupJoinTable:添加和更新是不能注释掉这个这样才能走自定义的连接表以及走他的钩子函数查询则不需要 添加文章并添加标签并自动关联
DB.Create(Article{Title: golang_study,Tags: []Tag{{Text: go},{Text: study}},})添加文章关联已有标签
//添加文章关联已有标签
var tag Tag
DB.Take(tag, text?, study)
DB.Create(Article{Title: how To Study,Tags: []Tag{tag},
})给已有文章关联标签
//直接操作连接表比较极端知道文章和tag的ID直接进行添加-------------
DB.Create(Article2tag{ArticleID: 3,TagID: 2,CreatedAt: time.Time{},
})//先查询相关标签在关联--------------------
var tags []Tag //这里主要根据tag切片作为识别切片名字可以随便起
DB.Find(tags, text in?, []string{go, study})var article Article
DB.Take(article, title?, gin)DB.Model(article).Association(Tags).Append(tags)替换已有文章的标签
//替换已有文章的标签
var article Article
DB.Preload(Tags).Take(article, 3) //preload中参数需严格对应,这里不需要preload好像也可以)
fmt.Println(article)
var tag Tag
DB.Take(tag, text?, go)
DB.Model(article).Association(Tags).Replace(tag)查询文章列表显示标签
//查询文章列表并显示标签
var articles []Article
DB.Preload(Tags).Find(articles)
fmt.Println(articles)自定义连接表主键 当定义的表复杂时gorm自动的主键名可能比较冗长我们可以通过自定义主键名来简单化 主要要注释的是joinForeignKey 连接主键ID joinReferences 关联主键ID
// 自定义主键部分-----------------------------------------
type Article struct {ID uintTitle stringTags []Tag gorm:many2many:article2tag;joinForeignKey:A_ID;joinReferences:T_ID
}type Tag struct {ID uintText stringArticles []Article gorm:many2many:article2tag;joinForeignKey:T_ID;joinReferences:A_ID //当使用反向引用时需要在setUpJoinTable时多设置一次这个表的
}// Article2tag 自定义连接表
type Article2tag struct {A_ID uint gorm:primaryKeyT_ID uint gorm:primaryKey //上两项即为连接表默认项CreatedAt time.Time //自定义添加一个创建时间字段
}操作连接表 当通过其他表来查连接表可能会不方便比如我们在这里查二者什么时候建立的关联即createat字段名
查询
传统查询文章列表显示标签 首先其无法进行分页操作经过如下修改也能分页
DB.Preload(Tags).Take(article, 1)
var tags []Tag
DB.Model(article).Limit(1).Association(Tags).Find(tags) //这样可以分页但是也无法查询连接表中其他字段如关联时间
fmt.Println(tags)若是直接在此时的连接表查询我们也只能得到文章和标签的id无法得到用户名及标签名 因此我们可以改一下连接表结构,将两张主表的结构体关联到连接表中具体可见如下代码所示
// Article2tag 自定义连接表
type Article2tag struct {ArticleID uint gorm:primaryKeyTagID uint gorm:primaryKey //上两项即为连接表默认项Article Article gorm:foreignKey:ArticleIDTag Tag gorm:foreignKey:TagIDCreatedAt time.Time //自定义添加一个创建时间字段
}查询相关写法可以参见该 链接
var articleTag []Article2tag
DB.Preload(Article).Preload(Tag).Where(map[string]any{Article_id: 1}).Find(articleTag) //大小写可忽略符号不可忽略具体需查看表内字段
fmt.Println(articleTag)
DB.Preload(Article).Preload(Tag).Where(article_id?, 1).Find(articleTag) //大小写可忽略符号不可忽略具体需查看表内字段
fmt.Println(articleTag)
DB.Preload(Article).Preload(Tag).Find(articleTag, article_id?, 1) //大小写可忽略符号不可忽略具体需查看表内字段
fmt.Println(articleTag)