GOrm多对多(关联查询)

一、概述

  现有两张表,一张表代表章节(chapter)、另外一张表代表集(episode)。一个章节中包含多集,一个集中有可能有视频也有可能没有视频,视频表(video)。

  表结构如下:

  1.章节表(chapter),ps:一个章节中包含了多集

  2.集表(episode),集中有视频

  3.视频表(video)

 

  要求:查询章节列表,并把章节中的所有集加载出来,并且把集中的视频也加载出来。效果如下:

  

  如果想要查询出来的表中的字段自动映射就需要用到gorm的Preload。

 

 

二、代码示例

  1.章节结构体(Chapter)

package entity

// "gorm.io/gorm"

// 章节结构体
type Chapter struct {
    // gorm.Model
    Id         int64     `json:"id"`
    VideoId    string    `json:"video_id"`
    Title      string    `json:"title"`
    Ordered    int       `json:"ordered"`
    CreateTime string    `json:"create_time"`
    UpdateTime string    `json:"update_time"`
    Sort       int       `json:"sort"`
    CreateUser int64     `json:"create_user"`
    UpdateUser int64     `json:"update_user"`
    Deleted    int       `json:"deleted"`
    Episodes   []Episode `json:"episodes" gorm:"foreignKey:ChapterId;"` // 其中foreignKey:ChapterId代表设置Episode结构体的ChapterId和chapter结构体的Id是关联关系(主外键关系)
    Video      Video     `json:"video" gorm:"foreignKey:VideoId;"`//其中foreignKey:VideoId代表设置video表的id和chapter表的VideoId字段是关联关系(主外键)关系
}

func (Chapter) TableName() string {//设置结构体对应的表名为:chapter
    return "chapter"
}

  2.集结构体(Episode)

package entity

// foreignKey    指定当前模型的列作为连接表的外键
// references    指定引用表的列名,其将被映射为连接表外键
// polymorphic    指定多态类型,比如模型名
// polymorphicValue    指定多态值、默认表名
// many2many    指定连接表表名
// joinForeignKey    指定连接表的外键列名,其将被映射到当前表
// joinReferences    指定连接表的外键列名,其将被映射到引用表
// constraint    关系约束,例如:OnUpdate、OnDelete

// "gorm.io/gorm"

// 集(集中包含章节)
type Episode struct {
    // gorm.Model
    Id         int64  `json:"id"`
    Title      string `json:"title"`
    Num        int    `json:"num"`
    Ordered    int    `json:"ordered"`
    PlayUrl    string `json:"play_url"`
    ChapterId  int64  `json:"chapter_id"`
    Free       int    `json:"free"`
    VideoId    int64  `json:"video_id"`
    CreateTime string `json:"create_time"`
    UpdateTime string `json:"update_time"`
    Sort       int    `json:"sort"`
    CreateUser int64  `json:"create_user"`
    UpdateUser int64  `json:"update_user"`
    Deleted    int    `json:"deleted"`
    Video      Video  `json:"video" gorm:"foreignKey:VideoId;"`//其中foreignKey:VideoId代表,设置video表的id和episode表的VideoId是关联关系(主外键关系),只有关联正确后才能够执行预加载
}

func (Episode) TableName() string {//代表Episode结构体对应的表名是episode
    return "episode"
}

  3.视频结构体(Video)

package entity

type Video struct {
    Id         int64   `json:"id"`
    Title      string  `json:"title"`
    Summary    string  `json:"summary"`
    CoverImg   string  `json:"cover_img"`
    Price      int64   `json:"price"`
    CreateTime string  `json:"create_time"`
    Point      float64 `json:"point"`
    UpdateTime string  `json:"update_time"`
    CreateUser int64   `json:"create_user"`
    UpdateUser int64   `json:"update_user"`
    Deleted    int64   `json:"deleted"`
}

func (Video) TableName() string {//代表Video结构体对应的数据库表名是video
    return "video"
}

  4.执行多表联查

func getECsHandler(context *gin.Context) {
    db := connectMySql().Debug()
  //定义一个章节列表切片,用于存储查询出来的章节列表
var chapters []entity.Chapter
  //Preload("Episodes")代表预加载episode表,其中Episodes代表Chapter结构体中定义的字段
  //Preload("video")代表预加载video表,其中Video代表Chapter或者Episodes结构体中定义的字段
  //然后把预加载出来的数据组合到chapters切片中 err :
= db.Preload("Episodes").Preload("Video").Find(&chapters).Error if err != nil { response.ShowError(400, "多表联查查询失败", context) return } response.ShowSuccess(chapters, context) }

  5.上面的db.Preload("Episodes").Preload("Video").Find(&chapters).Error执行的sql如下

SELECT * FROM `episode` WHERE `episode`.`chapter_id` IN (370,371,372,373,374,375,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,450,451,452,453,454,455,456,457,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,510,511,512,513,514,515,516,517,518,519,520,521,522,523,600,601,602,603,604,605,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726)
SELECT * FROM `video` WHERE `video`.`id` IN ('40','41','42','43','44','45','46','47','31','48')
SELECT * FROM `chapter`

 

posted on 2024-01-16 14:00  飘杨......  阅读(246)  评论(0编辑  收藏  举报