模型定义

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

例如:

  1. type User struct {
    ID uint
    Name string
    Email *string
    Age uint8
    Birthday *time.Time
    MemberNumber sql.NullString
    ActivedAt sql.NullTime
    CreatedAt time.Time
    UpdatedAt time.Time
    }

约定

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

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

gorm.Model

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

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

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

高级选项

字段级权限控制

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

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

  1. type User struct {
    Name string `gorm:"<-:create"` // 允许读和创建
    Name string `gorm:"<-:update"` // 允许读和更新
    Name string `gorm:"<-"` // 允许读和写(创建和更新)
    Name string `gorm:"<-:false"` // 允许读,禁止写
    Name string `gorm:"->"` // 只读(除非有自定义配置,否则禁止写)
    Name string `gorm:"->;<-:create"` // 允许读和写
    Name string `gorm:"->:false;<-:create"` // 仅创建(禁止从 db 读)
    Name string `gorm:"-"` // 读写操作均会忽略该字段
    }

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

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

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

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

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

嵌入结构体

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

  1. type User struct {
    gorm.Model
    Name string
    }
    // 等效于
    type User struct {
    ID uint `gorm:"primaryKey"`
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt gorm.DeletedAt `gorm:"index"`
    Name string
    }

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

  1. type Author struct {
    Name string
    Email string
    }

    type Blog struct {
    ID int
    Author Author `gorm:"embedded"`
    Upvotes int32
    }
    // 等效于
    type Blog struct {
    ID int64
    Name string
    Email string
    Upvotes int32
    }

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

  1. type Blog struct {
    ID int
    Author Author `gorm:"embedded;embeddedPrefix:author_"`
    Upvotes int32
    }
    // 等效于
    type Blog struct {
    ID int64
    AuthorName string
    AuthorEmail string
    Upvotes int32
    }

字段标签

声明 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_INSTREMENT
size指定列大小,例如:size:256
primaryKey指定列为主键
unique指定列为唯一
default指定列的默认值
precision指定列的精度
scale指定列大小
not null指定列为 NOT NULL
autoIncrement指定列为自动增长
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
commentadd comment for field when migration

关联标签

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