声明模型

原文:https://gorm.io/docs/models.html

Models are normal structs with basic Go types, pointers/alias of them or custom types implementing Scanner and Valuer interfaces

​ 模型是具有基本Go类型的普通结构体,或者是它们的指针/别名,或者是实现了ScannerValuer接口的自定义类型。

For Example:

​ 例如:

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

约定 Conventions

GORM prefers convention over configuration. By default, GORM uses ID as primary key, pluralizes struct name to snake_cases as table name, snake_case as column name, and uses CreatedAt, UpdatedAt to track creating/updating time

​ GORM 倾向于约定优于配置。默认情况下,GORM使用ID作为主键,将结构体名称转换为snake_cases作为表名,snake_case作为列名,并使用CreatedAtUpdatedAt来追踪创建/更新时间。

If you follow the conventions adopted by GORM, you’ll need to write very little configuration/code. If convention doesn’t match your requirements, GORM allows you to configure them

​ 如果您遵循GORM采用的约定,您只需要编写很少的配置/代码。如果约定不符合您的要求,GORM允许您进行配置

gorm.Model

GORM defined a gorm.Model struct, which includes fields ID, CreatedAt, UpdatedAt, DeletedAt

​ GORM定义了一个gorm.Model结构体,其中包含字段IDCreatedAtUpdatedAtDeletedAt

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

You can embed it into your struct to include those fields, refer Embedded Struct

​ 您可以将其嵌入到您的结构体中以包含这些字段,请参阅嵌入式结构体

高级功能 Advanced

字段级权限控制 Field-Level Permission

Exported fields have all permissions when doing CRUD with GORM, and GORM allows you to change the field-level permission with tag, so you can make a field to be read-only, write-only, create-only, update-only or ignored

​ 导出的字段在进行GORM CRUD操作时具有所有权限,并且GORM允许您使用标签更改字段级权限,因此您可以使一个字段只读、只写、只创建、只更新或被忽略。

NOTE ignored fields won’t be created when using GORM Migrator to create table

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
type User struct {
  Name string `gorm:"<-:create"` // 允许读和创建 allow read and create
  Name string `gorm:"<-:update"` // 允许读和更新 allow read and update
  Name string `gorm:"<-"`        // 允许读和写(创建和更新) allow read and write (create and update)
  Name string `gorm:"<-:false"`  // 允许读,禁止写 allow read, disable write permission
  Name string `gorm:"->"`        // 只读(除非有自定义配置,否则禁止写) readonly (disable write permission unless it configured)
  Name string `gorm:"->;<-:create"` // 允许读和写 allow read and create
  Name string `gorm:"->:false;<-:create"` // 仅创建(禁止从 db 读) createonly (disabled read from db)
  Name string `gorm:"-"`            // 通过 struct 读写会忽略该字段 ignore this field when write and read with struct
  Name string `gorm:"-:all"`        // 通过 struct 读写、迁移会忽略该字段 ignore this field when write, read and migrate with struct
  Name string `gorm:"-:migration"`  // 通过 struct 迁移会忽略该字段 ignore this field when migrate with struct
}

创建/更新时间追踪 Time/Unix (Milli/Nano) 秒 Creating/Updating Time/Unix (Milli/Nano) Seconds Tracking

GORM use CreatedAt, UpdatedAt to track creating/updating time by convention, and GORM will set the current time when creating/updating if the fields are defined

​ GORM使用CreatedAtUpdatedAt按照约定来追踪创建/更新时间,如果这些字段被定义了,GORM会在创建/更新时设置当前时间。

To use fields with a different name, you can configure those fields with tag autoCreateTime, autoUpdateTime

​ 如果你想使用不同名称的字段,你可以使用标签autoCreateTimeautoUpdateTime来配置这些字段。

If you prefer to save UNIX (milli/nano) seconds instead of time, you can simply change the field’s data type from time.Time to int

​ 如果你更喜欢保存UNIX(毫秒/纳秒)而不是时间,你可以直接将字段的数据类型从time.Time更改为int

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

嵌入式结构体 Embedded Struct

For anonymous fields, GORM will include its fields into its parent struct, for example:

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

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

For a normal struct field, you can embed it with the tag embedded, for example:

​ 对于普通结构体字段,你可以通过使用embedded标签将其嵌入,例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
type Author struct {
  Name  string
  Email string
}

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

And you can use tag embeddedPrefix to add prefix to embedded fields’ db name, for example:

​ 你还可以使用embeddedPrefix标签为嵌入式字段的数据库名称添加前缀,例如:

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

字段标签 Fields Tags

Tags are optional to use when declaring models, GORM supports the following tags:

​ 声明模型时使用标签是可选的,GORM支持以下标签:

Tags are case insensitive, however camelCase is preferred.

​ 标签不区分大小写,但是camelCase更受欢迎。

标签名 Tag Name描述 Description
column列的数据库名称 column db name
type列的数据类型,推荐使用兼容的通用类型,例如:bool、int、uint、float、string、time、bytes,这些类型适用于所有数据库,并且可以与其他标签一起使用,如not nullsizeautoIncrement等指定的数据库数据类型,如varbinary(8)。当使用指定的数据库数据类型时,它需要是一个完整的数据库数据类型,例如:MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT
column data type, prefer to use compatible general type, e.g: bool, int, uint, float, string, time, bytes, which works for all databases, and can be used with other tags together, like not null, size, autoIncrement… specified database data type like varbinary(8) also supported, when using specified database data type, it needs to be a full database data type, for example: MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT
serializer指定如何将数据序列化和反序列化到数据库的序列化器,例如:serializer:json/gob/unixtime
specifies serializer for how to serialize and deserialize data into db, e.g: serializer:json/gob/unixtime
size指定列数据大小/长度,例如:size:256
specifies column data size/length, e.g: size:256
primaryKey指定列为主键
specifies column as primary key
unique指定列为唯一
specifies column as unique
default指定列的默认值
specifies column default value
precision指定列的精度
specifies column precision
scale指定列的小数位数
specifies column scale
not null指定列为NOT NULL
specifies column as NOT NULL
autoIncrement指定列为可自动递增
specifies column auto incrementable
autoIncrementIncrement自动递增步长,控制连续列值之间的间隔
auto increment step, controls the interval between successive column values
embedded嵌入字段
embed the field
embeddedPrefix嵌入式字段的名称前缀
column name prefix for embedded fields
autoCreateTime创建时追踪当前时间,对于int字段,它将追踪unix秒,使用值nano/milli来追踪unix nano/milli秒,例如:autoCreateTime:nano
track 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
autoUpdateTime创建/更新时追踪当前时间,对于int字段,它将追踪unix秒,使用值nano/milli来追踪unix nano/milli秒,例如:autoUpdateTime:milli
track 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
index使用选项创建索引,为多个字段创建复合索引,参考Indexes以获取详细信息
create index with options, use same name for multiple fields creates composite indexes, refer Indexes for details
uniqueIndexindex相同,但创建唯一索引
same as index, but create uniqued index
check创建检查约束,例如:check:age > 13,参考Constraints
creates check constraint, eg: check:age > 13, refer Constraints
<-设置字段的写权限,<-:create仅创建字段,<-:update仅更新字段,<-:false无写权限,<-创建和更新权限
set field’s write permission, <-:create create-only field, <-:update update-only field, <-:false no write permission, <- create and update permission
->设置字段的读权限,->:false无读权限
set field’s read permission, ->:false no read permission
-忽略此字段,-无读/写权限,-:migration无迁移权限,-:all无读/写/迁移权限
ignore this field, - no read/write permission, -:migration no migrate permission, -:all no read/write/migrate permission
comment在迁移时为字段添加注释
add comment for field when migration

关联标签 Associations Tags

GORM allows configure foreign keys, constraints, many2many table through tags for Associations, check out the Associations section for details

​ GORM允许通过关联标签配置外键、约束和多对多表。有关详细信息,请参阅关联部分

最后修改 October 10, 2024: 更新 (a4b8f85)