GORM 自动设置 MySQL 数据的创建和修改时间
- # go
- # gorm
- # mysql
使用 GORM 操作 MySQL 数据表时,经常会遇到一个很普通但很容易反复处理的问题:创建时间和更新时间应该由谁来设置?
常见做法有几种:使用 GORM 的约定字段、给自定义字段添加时间追踪标签、把时间更新交给数据库,或者直接嵌入 gorm.Model。
使用默认支持字段
GORM 约定使用 CreatedAt 和 UpdatedAt 来追踪记录的创建时间和更新时间。只要模型里定义了这两个字段,GORM 在创建和更新记录时就会自动填充当前时间。
type User struct {
CreatedAt time.Time `gorm:"column:created_at;" json:"created_at"` // 创建时间
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` // 更新时间
}
GORM 文档 中的说明是:如果定义了 CreatedAt、UpdatedAt 字段,GORM 会在创建、更新时自动填充当前时间。
使用自定义字段
如果字段名不是 CreatedAt、UpdatedAt,可以通过 autoCreateTime 和 autoUpdateTime 标签告诉 GORM 这些字段分别用于创建时间和更新时间。
type User struct {
Created time.Time `gorm:"column:created;autoCreateTime" json:"created"`
Updated time.Time `gorm:"column:updated;autoUpdateTime" json:"updated"` // 更新时间
}
这种方式适合数据库里已经有固定字段名,或者项目希望字段命名更贴近现有表结构的情况。
交给 MySQL 维护时间
也可以直接在数据库层设置 CURRENT_TIMESTAMP,让 MySQL 在插入和更新时维护时间。
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
如果希望数据库负责这两个字段,结构体里可以把字段标记为只读,避免 GORM 写入时覆盖它们:
type User struct {
CreatedAt time.Time `gorm:"column:created_at;<-:false" json:"created_at"` // 创建时间
UpdatedAt time.Time `gorm:"column:updated_at;<-:false" json:"updated_at"` // 更新时间
}
<-:false 是 GORM 的字段级权限标签,表示允许读取,但禁止写入。这样应用侧仍然能读取时间字段,实际写入和更新时间由 MySQL 完成。
使用 gorm.Model
GORM 内置了一个 gorm.Model 结构体,里面包含常见的模型字段:
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
使用时可以直接嵌入模型:
type User struct {
gorm.Model
Name string
}
这种方式很方便,适合接受 GORM 默认字段设计的场景。不过如果你需要自定义字段名、JSON 标签、数据库列名,或者不需要软删除字段,手动定义字段会更直接。
gorm.Model 包含的字段包括:
ID:记录的主键。CreatedAt:创建记录时自动设置。UpdatedAt:更新记录时自动更新。DeletedAt:用于软删除。
初始化结构体数据时,通常不要主动给这些自动时间字段设置值,让 GORM 或数据库按约定处理即可。
参考:GORM 模型定义。