GORM基础知识——建表、外键设置| 青训营

1,160 阅读4分钟

继GORM快速入门,这次我记录GORM的基础用法,包括:创建表、设置表约束、数据增删改查等,若一篇写不完,打算分成几篇 绝对不是在凑数量。本笔记为官方文档加加上个人理解,肯定没有覆盖所有知识,详细请见GORM中文文档

下面正文开始👇👇👇

创建表结构

快速入门可知,我们创建一个结构体,之后通过AutoMigrate(&struckname{})即可创建相应的表结构。

GORM 倾向于约定优于配置 默认情况下,GORM 使用 ID 作为主键,使用结构体名的蛇形复数作为表名,字段名的蛇形命名作为列名,并使用 CreatedAtUpdatedAt 字段追踪创建、更新时间。这里我对蛇形命名的理解为“全小写以下划线连接单词”。详见约定

举个例子:

image.png

如图我通过结构体Company创建了一个名为companies的表结构 (这里它貌似会识别出单词然后改成负数形式) 然后里面的字段为id、name,主键为id,如下图:

image.png

如果你不想用它约定的主键也可以自己配置,只需在字段后面加`gorm:"primaryKey"`声明

image.png 复合主键只要在多个字段后面加`gorm:"primaryKey"`即可,默认情况下,整型 PrioritizedPrimaryField 启用了 AutoIncrement,要禁用它,您需要为整型字段关闭 autoIncrement

type Product struct {   
    CategoryID uint64 `gorm:"primaryKey;autoIncrement:false"`   
    TypeID     uint64 `gorm:"primaryKey;autoIncrement:false"` 
}

外键约束

在GORM中外键被称为关联,实体关系中的一对一、一对多、多对多的关系也被分为belongs to、has one、has many、many to many

belongs to关系

belongs to 会与另一个模型建立了一对一的连接。 这种模型的每一个实例都“属于”另一个模型的一个实例。

例如,您的应用包含 user 和 company,并且每个 user 能且只能被分配给一个 company。下面的类型就表示这种关系。 注意,在 User 对象中,有一个和 Company 一样的 CompanyID。 默认情况下, CompanyID被隐含地用来在 User 和 Company 之间创建一个外键关系, 因此必须包含在 User 结构体中才能填充 Company 内部结构体。如下段声明User 属于 CompanyCompanyID 是外键 。

type User struct {   
    gorm.Model   
    Name      string   
    CompanyID int   
    Company   Company 
}  
type Company struct {   
    ID   int   
    Name string 
}

这里就默认CompanyID是User的外键,参考Company的主键ID。这里你只需要AutoMigrate(&User{}) companies表也会自动创建。

可以看到声明完的情况如图: image.png users表外键情况如图: image.png

要定义一个 belongs to 关系,数据库的表中必须存在外键。默认情况下,外键的名字,使用拥有者的类型名称加上表的主键的字段名字。但是如果你想有自己的命名规则,则需要显式地声明你的外键`gorm:"foreignKey:CompanyRefer"`,如下图所示:

image.png

如果你想修改外键的参考字段则需使用`gorm:"references:Code"`显式声明参考的字段 ,如下图:

image.png 注意点:如果你想创建belongs to关系,但你的外键名和参考字段名刚好相同了,就需要显式声明,否则就会被认为是has one关系

has one关系

has one 与另一个模型建立一对一的关联,但它和一对一关系有些许不同。 这种关联表明一个模型的每个实例都包含或拥有另一个模型的一个实例。

例如,您的应用包含 user 和 credit card 模型,且每个 user 只能有一张 credit card。声明如下

// User 有一张 CreditCard,UserID 是外键 
type User struct {   
    gorm.Model   
    CreditCard CreditCard 
}  
type CreditCard struct {   
    gorm.Model   
    Number string   
    UserID uint 
}

可以看出has one 与belongs to关系同作为一对一关系,声明方式还是有点不同的。has one 关系,把附属者 CreditCard 作为所有者 User 的一个字段,更自然;而 belongs to 关系,把所有者 User 作为附属者 CreditCard 的一个字段。有点绕,其实就是声明上把外键放哪个表的问题了。 貌似has one的迁移顺序不能变,否则CreditCard的生成表没有外键
db.AutoMigrate(&User{})
db.AutoMigrate(&CreditCard{})

你可以通过声明的方式修改默认的外键约束,比如这里声明了联级更新,删除置空

`gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`

后面的has many、many to many关系可以参考GORM中文文档,他们的用法差异主要在预加载处,届时会展示实际效果。

----分割线----