GORM simplifies database interactions by mapping Go structs to database tables. Understanding how to declare models in GORM is fundamental for leveraging its full capabilities.
模型定义
Models are defined using normal structs. These structs can contain fields with basic Go types, pointers or aliases of these types, or even custom types, as long as they implement the Scanner and Valuer interfaces from the database/sql
package
Consider the following example of a User
model:
type User struct { |
In this model:
- Basic data types like
uint
,string
, anduint8
are used directly. - Pointers to types like
*string
and*time.Time
indicate nullable fields. sql.NullString
andsql.NullTime
from thedatabase/sql
package are used for nullable fields with more control.CreatedAt
andUpdatedAt
are special fields that GORM automatically populates with the current time when a record is created or updated.
In addition to the fundamental features of model declaration in GORM, it’s important to highlight the support for serialization through the serializer tag. This feature enhances the flexibility of how data is stored and retrieved from the database, especially for fields that require custom serialization logic, See Serializer for a detailed explanation
约定
Primary Key: GORM uses a field named
ID
as the default primary key for each model.Table Names: By default, GORM converts struct names to
snake_case
and pluralizes them for table names. For instance, aUser
struct becomesusers
in the database.Column Names: GORM automatically converts struct field names to
snake_case
for column names in the database.Timestamp Fields: GORM uses fields named
CreatedAt
andUpdatedAt
to automatically track the creation and update times of records.
Following these conventions can greatly reduce the amount of configuration or code you need to write. However, GORM is also flexible, allowing you to customize these settings if the default conventions don’t fit your requirements. You can learn more about customizing these conventions in GORM’s documentation on conventions.
gorm.Model
GORM provides a predefined struct named gorm.Model
, which includes commonly used fields:
// gorm.Model 的定义 |
Embedding in Your Struct: You can embed
gorm.Model
directly in your structs to include these fields automatically. This is useful for maintaining consistency across different models and leveraging GORM’s built-in conventions, refer Embedded StructFields Included:
ID
: A unique identifier for each record (primary key).CreatedAt
: Automatically set to the current time when a record is created.UpdatedAt
: Automatically updated to the current time whenever a record is updated.DeletedAt
: Used for soft deletes (marking records as deleted without actually removing them from the database).
高级选项
字段级权限控制
可导出的字段在使用 GORM 进行 CRUD 时拥有全部的权限,此外,GORM 允许您用标签控制字段级别的权限。这样您就可以让一个字段的权限是只读、只写、只创建、只更新或者被忽略
注意: 使用 GORM Migrator 创建表时,不会创建被忽略的字段
type User struct { |
创建/更新时间追踪(纳秒、毫秒、秒、Time)
GORM 约定使用 CreatedAt
、UpdatedAt
追踪创建/更新时间。如果您定义了这种字段,GORM 在创建、更新时会自动填充 当前时间
要使用不同名称的字段,您可以配置 autoCreateTime
、autoUpdateTime
标签。
如果您想要保存 UNIX(毫/纳)秒时间戳,而不是 time,您只需简单地将 time.Time
修改为 int
即可
type User struct { |
嵌入结构体
对于匿名字段,GORM 会将其字段包含在父结构体中,例如:
type User struct { |
对于正常的结构体字段,你也可以通过标签 embedded
将其嵌入,例如:
type Author struct { |
并且,您可以使用标签 embeddedPrefix
来为 db 中的字段名添加前缀,例如:
type Blog struct { |
声明 model 时,tag 是可选的,GORM 支持以下 tag: tag 名大小写不敏感,但建议使用 camelCase
风格
标签名 | 说明 |
---|---|
column | 指定 db 列名 |
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 | 指定列为 NOT NULL |
autoIncrement | 指定列为自动增长 |
autoIncrementIncrement | 自动步长,控制连续记录之间的间隔 |
embedded | 嵌套字段 |
embeddedPrefix | 嵌入字段的列名前缀 |
autoCreateTime | 创建时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,您可以使用 nano /milli 来追踪纳秒、毫秒时间戳,例如:autoCreateTime:nano |
autoUpdateTime | 创建/更新时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,您可以使用 nano /milli 来追踪纳秒、毫秒时间戳,例如:autoUpdateTime:milli |
index | 根据参数创建索引,多个字段使用相同的名称则创建复合索引,查看 索引 获取详情 |
uniqueIndex | 与 index 相同,但创建的是唯一索引 |
check | 创建检查约束,例如 check:age > 13 ,查看 约束 获取详情 |
<- | 设置字段写入的权限, <-:create 只创建、<-:update 只更新、<-:false 无写入权限、<- 创建和更新权限 |
-> | 设置字段读的权限,->:false 无读权限 |
- | 忽略该字段,- 表示无读写,-:migration 表示无迁移权限,-:all 表示无读写迁移权限 |
comment | 迁移时为字段添加注释 |
关联标签
GORM 允许通过标签为关联配置外键、约束、many2many 表,详情请参考 关联部分