模型定义

模型是标准的 struct,由 Go 的基本数据类型、实现了 ScannerValuer 接口的自定义类型及其指针或别名组成

例如:

  1. type User struct {
  2. ID uint
  3. Name string
  4. Email *string
  5. Age uint8
  6. Birthday *time.Time
  7. MemberNumber sql.NullString
  8. ActivatedAt sql.NullTime
  9. CreatedAt time.Time
  10. UpdatedAt time.Time
  11. }

约定

GORM 倾向于约定,而不是配置。默认情况下,GORM 使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAtUpdatedAt 字段追踪创建、更新时间

遵循 GORM 已有的约定,可以减少您的配置和代码量。如果约定不符合您的需求,GORM 允许您自定义配置它们

gorm.Model

GORM 定义一个 gorm.Model 结构体,其包括字段 IDCreatedAtUpdatedAtDeletedAt

  1. // gorm.Model 的定义
  2. type Model struct {
  3. ID uint `gorm:"primaryKey"`
  4. CreatedAt time.Time
  5. UpdatedAt time.Time
  6. DeletedAt gorm.DeletedAt `gorm:"index"`
  7. }

您可以将它嵌入到您的结构体中,以包含这几个字段,详情请参考 嵌入结构体

高级选项

字段级权限控制

可导出的字段在使用 GORM 进行 CRUD 时拥有全部的权限,此外,GORM 允许您用标签控制字段级别的权限。这样您就可以让一个字段的权限是只读、只写、只创建、只更新或者被忽略

注意: 使用 GORM Migrator 创建表时,不会创建被忽略的字段

  1. type User struct {
  2. Name string `gorm:"<-:create"` // allow read and create
  3. Name string `gorm:"<-:update"` // allow read and update
  4. Name string `gorm:"<-"` // allow read and write (create and update)
  5. Name string `gorm:"<-:false"` // allow read, disable write permission
  6. Name string `gorm:"->"` // readonly (disable write permission unless it configured)
  7. Name string `gorm:"->;<-:create"` // allow read and create
  8. Name string `gorm:"->:false;<-:create"` // createonly (disabled read from db)
  9. Name string `gorm:"-"` // ignore this field when write and read with struct
  10. Name string `gorm:"-:all"` // ignore this field when write, read and migrate with struct
  11. Name string `gorm:"-:migration"` // ignore this field when migrate with struct
  12. }

创建/更新时间追踪(纳秒、毫秒、秒、Time)

GORM 约定使用 CreatedAtUpdatedAt 追踪创建/更新时间。如果您定义了这种字段,GORM 在创建、更新时会自动填充 当前时间

要使用不同名称的字段,您可以配置 autoCreateTimeautoUpdateTime 标签

如果您想要保存 UNIX(毫/纳)秒时间戳,而不是 time,您只需简单地将 time.Time 修改为 int 即可

  1. type User struct {
  2. CreatedAt time.Time // 在创建时,如果该字段值为零值,则使用当前时间填充
  3. UpdatedAt int // 在创建时该字段值为零值或者在更新时,使用当前时间戳秒数填充
  4. Updated int64 `gorm:"autoUpdateTime:nano"` // 使用时间戳填纳秒数充更新时间
  5. Updated int64 `gorm:"autoUpdateTime:milli"` // 使用时间戳毫秒数填充更新时间
  6. Created int64 `gorm:"autoCreateTime"` // 使用时间戳秒数填充创建时间
  7. }

嵌入结构体

对于匿名字段,GORM 会将其字段包含在父结构体中,例如:

  1. type User struct {
  2. gorm.Model
  3. Name string
  4. }
  5. // 等效于
  6. type User struct {
  7. ID uint `gorm:"primaryKey"`
  8. CreatedAt time.Time
  9. UpdatedAt time.Time
  10. DeletedAt gorm.DeletedAt `gorm:"index"`
  11. Name string
  12. }

对于正常的结构体字段,你也可以通过标签 embedded 将其嵌入,例如:

  1. type Author struct {
  2. Name string
  3. Email string
  4. }
  5. type Blog struct {
  6. ID int
  7. Author Author `gorm:"embedded"`
  8. Upvotes int32
  9. }
  10. // 等效于
  11. type Blog struct {
  12. ID int64
  13. Name string
  14. Email string
  15. Upvotes int32
  16. }

并且,您可以使用标签 embeddedPrefix 来为 db 中的字段名添加前缀,例如:

  1. type Blog struct {
  2. ID int
  3. Author Author `gorm:"embedded;embeddedPrefix:author_"`
  4. Upvotes int32
  5. }
  6. // 等效于
  7. type Blog struct {
  8. ID int64
  9. AuthorName string
  10. AuthorEmail string
  11. Upvotes int32
  12. }

字段标签

声明 model 时,tag 是可选的,GORM 支持以下 tag: tag 名大小写不敏感,但建议使用 camelCase 风格

标签名说明
column指定 db 列名
type列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not nullsize, autoIncrement… 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO_INCREMENT
serializerspecifies serializer for how to serialize and deserialize data into db, e.g: serializer:json/gob/unixtime
sizespecifies column data size/length, e.g: size:256
primaryKeyspecifies column as primary key
uniquespecifies column as unique
defaultspecifies column default value
precisionspecifies column precision
scalespecifies column scale
not nullspecifies column as NOT NULL
autoIncrementspecifies column auto incrementable
autoIncrementIncrementauto increment step, controls the interval between successive column values
embeddedembed the field
embeddedPrefixcolumn name prefix for embedded fields
autoCreateTimetrack current time when creating, for int fields, it will track unix seconds, use value nano/milli to track unix nano/milli seconds, e.g: autoCreateTime:nano
autoUpdateTimetrack current time when creating/updating, for int fields, it will track unix seconds, use value nano/milli to track unix nano/milli seconds, e.g: autoUpdateTime:milli
indexcreate index with options, use same name for multiple fields creates composite indexes, refer Indexes for details
uniqueIndexsame as index, but create uniqued index
checkcreates check constraint, eg: check:age > 13, refer Constraints
<-set field’s write permission, <-:create create-only field, <-:update update-only field, <-:false no write permission, <- create and update permission
->set field’s read permission, ->:false no read permission
-ignore this field, - no read/write permission, -:migration no migrate permission, -:all no read/write/migrate permission
commentadd comment for field when migration

关联标签

GORM 允许通过标签为关联配置外键、约束、many2many 表,详情请参考 关联部分