聊一聊GORM的关联模式 | 青训营

77 阅读3分钟

聊一聊GORM的关联模式

在本次青训营项目中,要求做一个简单的抖音后端,其中涉及到一对多以及多对多的实体关系。而在阅读gorm的官方文档时,其中的一些表述可能不是特别清晰,尤其是对初学者可能不太清楚他在讲些什么。本文旨在阐述gorm的关联,其中包括Belongs to、Has One、Has Many、Many To Many。希望读者在阅读本文后会有一个对gorm关联的基本了解。

[官方文档]  gorm.io/zh_CN/docs/…

Belongs To

type Video struct {
    gorm.Model
    Name   string
    UserID int
    User User
}
​
type User struct {
    gorm.Model
    Name   string
}

这里有两个结构体,一个Video,一个User。二者是属于的关系,即 Video 属于(Belongs To) User。在初读文档时可能会很直接的认为Video内嵌套了User,那么使用GORM创建表时也会在videos表内创建User结构的字段,那这样似乎就不太满足开发需求了。但事实上GORM会自动的创建两张表并通过外键的方式链接Video.UserID和User.ID。

我们通过代码跑一下

func BelongsTo() {
    db.AutoMigrate(&Video{})
}

在这里我们只在代码中指明创建了Video的表,但是由于Video关联了User所以GORM会自动的也将User表创建。

image-20230803132620499.png

users:

image-20230803132636928.png

videos:

image-20230803132647857.png

但是相反的如果只知名User则不会创建Video表,因为在User的结构体中无法判断User和Video的关系。

Has One

Has One关系其实就是Belongs To相反的关系,从下面的结构体可以清晰的看出

//User 有一个Video, UserID 是外键
type Video struct {
    gorm.Model
    Name   string
    UserID int
}
​
type User struct {
    gorm.Model
    Name  string
    Video Video 
}

同时Has One的建表逻辑与Belongs To 的建表逻辑相同

Has Many

//User 有很多个Video, UserID 是外键
type Video struct {
    gorm.Model
    Name   string
    UserID int
}
​
type User struct {
    gorm.Model
    Name  string
    Video []Video 
}

自动建表所得:

users:

image-20230803132636928.png

videos:

image-20230803132647857.png

多态关联

在上述两种关系的应用中,时常出现多表添加关系,每次添加一张表,都需要重新修改表的结构,增加外键,导致维护表的工作量增加,此时需要多态的概念来简化工作。

不使用多态:

type Video struct {
    gorm.Model
    Name   string
    MaleUserID int
    FemaleUserID int
}
​
type MaleUser struct {
    gorm.Model
    Name  string
    Video []Video 
}
​
type FemaleUser struct{
    gorm.Model
    Name  string
    Video []Video 
}

使用多态:

type Video struct {
    gorm.Model
    Name      string
    OwnerID   int
    OwnerType int
}
​
type MaleUser struct {
    gorm.Model
    Name  string
    Video []Video `gorm:"polymorphic:Owner;"`
}
​
type FemaleUser struct {
    gorm.Model
    Name  string
    Video []Video `gorm:"polymorphic:Owner;"`
}

FemaleUser:

image-20230803135746411.png

MaleUser:

image-20230803135747229.png

Videos:

image-20230803135759051.png

Many To Many

假设一个用户有多个视频,同时一个视频属于多个用户,那么这种关系就是多对多关系。在GORM中,通过AutoMigrate创建多对多关系,会自动创建连接表,以反映Video与User的关系。

模型:

type Video struct {
    gorm.Model
    Name   string
    Users  []User   `gorm:"many2many:users_videos;"`
}
​
type User struct {
    gorm.Model
    Name  string
    Videos []Video `gorm:"many2many:users_videos;"`
}

必须要加gorm:"many2many:连接表名;" 这个标签,否则通过AutoMigrate创建表时会发生错误,无法创建表

User:

image-20230803144626074.png

Video:

image-20230803144643338.png

连接表:

image-20230803144608932.png

到这里我们已经基本了解了GORM的关联模式,同时在GORM关联模式中还有许多标签以及CRUD使用方法。如果想要了解可以自行前往官方文档进行查看。