GORM 通过将 Go 结构体映射到数据库表来简化数据库交互。了解如何在 GORM 中声明模型是利用其全部功能的基础。
声明模型
模型使用普通的结构体定义。这些结构体可以包含具有基本 Go 类型、指针或这些类型的别名,甚至是自定义类型的字段,只要它们实现了 database/sql
包中的 Scanner 和 Valuer 接口
考虑以下 User
模型的示例
type User struct { |
在这个模型中
- 基本数据类型,如
uint
、string
和uint8
,直接使用。 - 指向类型的指针,如
*string
和*time.Time
,表示可为空的字段。 database/sql
包中的sql.NullString
和sql.NullTime
用于需要更多控制的可为空字段。CreatedAt
和UpdatedAt
是特殊字段,GORM 会在创建或更新记录时自动使用当前时间填充它们。
除了 GORM 中模型声明的基本功能外,重要的是要强调通过序列化器标签对序列化的支持。此功能增强了从数据库存储和检索数据的灵活性,特别是对于需要自定义序列化逻辑的字段,有关详细说明,请参阅 序列化器
约定
主键:GORM 使用名为
ID
的字段作为每个模型的默认主键。表名:默认情况下,GORM 会将结构体名称转换为
snake_case
并将其复数形式用于表名。例如,User
结构体在数据库中变为users
。列名:GORM 会自动将结构体字段名称转换为
snake_case
,以用于数据库中的列名。时间戳字段:GORM 使用名为
CreatedAt
和UpdatedAt
的字段来自动跟踪记录的创建时间和更新时间。
遵循这些约定可以大大减少您需要编写的配置或代码量。但是,GORM 也很灵活,允许您在默认约定不符合您的要求时自定义这些设置。您可以在 GORM 关于 约定 的文档中了解更多有关自定义这些约定的信息。
gorm.Model
GORM 提供了一个名为 gorm.Model
的预定义结构体,其中包含常用的字段
// gorm.Model definition |
嵌入到您的结构体中:您可以直接在结构体中嵌入
gorm.Model
以自动包含这些字段。这对于维护不同模型之间的一致性和利用 GORM 的内置约定非常有用,请参阅 嵌入式结构体包含的字段:
ID
:每条记录的唯一标识符(主键)。CreatedAt
:在创建记录时自动设置为当前时间。UpdatedAt
:每当记录更新时自动更新为当前时间。DeletedAt
:用于软删除(将记录标记为已删除,而不实际从数据库中删除它们)。
高级
字段级权限
使用 GORM 进行 CRUD 操作时,导出的字段具有所有权限,并且 GORM 允许您使用标签更改字段级权限,因此您可以将字段设置为只读、只写、只创建、只更新或忽略
注意 使用 GORM Migrator 创建表时,将不会创建被忽略的字段
type User struct { |
创建/更新时间/Unix(毫秒/纳秒)秒跟踪
GORM 按照惯例使用 CreatedAt
、UpdatedAt
来跟踪创建/更新时间,如果定义了这些字段,GORM 将在创建/更新时设置 当前时间
要使用具有不同名称的字段,可以使用标签 autoCreateTime
、autoUpdateTime
配置这些字段
如果您希望保存 UNIX(毫秒/纳秒)秒而不是时间,则只需将字段的数据类型从 time.Time
更改为 int
即可
type User struct { |
嵌入结构体
对于匿名字段,GORM 会将其字段包含在其父结构体中,例如
type User struct { |
对于普通的结构体字段,可以使用标签 embedded
来嵌入它,例如
type Author struct { |
并且可以使用标签 embeddedPrefix
为嵌入字段的数据库名称添加前缀,例如
type Blog struct { |
在声明模型时,标签是可选的,GORM 支持以下标签
标签不区分大小写,但建议使用 camelCase
形式。
标签名称 | 描述 |
---|---|
column | 数据库列名 |
type | 列数据类型,建议使用兼容的通用类型,例如:bool、int、uint、float、string、time、bytes,这些类型适用于所有数据库,并且可以与其他标签一起使用,例如 not null 、size 、autoIncrement ... 也支持指定数据库数据类型,例如 varbinary(8) ,当使用指定的数据库数据类型时,它需要是一个完整的数据库数据类型,例如:MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT |
serializer | 指定如何将数据序列化和反序列化到数据库的序列化器,例如:serializer:json/gob/unixtime |
size | 指定列数据大小/长度,例如:size:256 |
primaryKey | 指定列为主键 |
unique | 指定列为唯一 |
default | 指定列默认值 |
precision | 指定列精度 |
scale | 指定列小数位数 |
not null | 指定列为非空 |
autoIncrement | 指定列自动递增 |
autoIncrementIncrement | 自动递增步长,控制连续列值之间的间隔 |
embedded | 嵌入字段 |
embeddedPrefix | 嵌入字段的列名前缀 |
autoCreateTime | 在创建时跟踪当前时间,对于 int 字段,它将跟踪 Unix 秒数,使用值 nano /milli 跟踪 Unix 纳秒/毫秒,例如:autoCreateTime:nano |
autoUpdateTime | 在创建/更新时跟踪当前时间,对于 int 字段,它将跟踪 Unix 秒数,使用值 nano /milli 跟踪 Unix 纳秒/毫秒,例如:autoUpdateTime:milli |
index | 创建带选项的索引,对多个字段使用相同的名称创建复合索引,有关详细信息,请参阅索引 |
uniqueIndex | 与 index 相同,但创建唯一索引 |
check | 创建检查约束,例如:check:age > 13 ,请参阅约束 |
<- | 设置字段的写权限,<-:create 只读字段,<-:update 只更新字段,<-:false 无写权限,<- 创建和更新权限 |
-> | 设置字段的读权限,->:false 无读权限 |
- | 忽略此字段,- 无读/写权限,-:migration 无迁移权限,-:all 无读/写/迁移权限 |
comment | 在迁移时为字段添加注释 |
关联标签
GORM 允许通过关联的标签配置外键、约束、多对多表,有关详细信息,请查看关联部分