阅读gorm model文档

This commit is contained in:
asahi
2025-01-15 22:59:21 +08:00
parent b8c173c529
commit 0b58982907

View File

@@ -1,6 +1,13 @@
- [GORM](#gorm)
- [QuickStart](#quickstart)
- [Declaring Models](#declaring-models)
- [约定](#约定)
- [gorm.Model](#gormmodel)
- [Advanced](#advanced)
- [Field Level Permission](#field-level-permission)
- [CreatedAt / UpdatedAt](#createdat--updatedat)
- [struct embedded](#struct-embedded)
- [field tags](#field-tags)
# GORM
@@ -74,6 +81,233 @@ type User struct {
- 基础类型的字段可以直接访问,例如`uint, uint8, string`
- 指针类型,例如`*time.Time, *string`等,代表该字段值可为空
- `sql/database`中的`sql.NullString``sql.NullTime`类型,也代表该字段可为空
- `CreateAt`字段和`UpdatedAt`字段是由Gorm管理的字段当Record被创建或更新时该字段的值会自动被注入为当前时间
- `CreatedAt`字段和`UpdatedAt`字段是由Gorm管理的字段当Record被创建或更新时该字段的值会自动被注入为当前时间
- `Non-exported fields`(首字母不是大写)并不会被映射
### 约定
- `Primary Key`: 对于每个Modelgorm中将name为`ID`的field看作默认primary key
- `Table names` 默认情况下gorm将struct name转换为`snake_case`,并将`snake_case``复数化`作为表名。例如,`User`struct对应的表名为`users``GormUserName`对应的表名为`gorm_user_names`
- `Column Names`: gorm会自动将field name转化为`snake_case`,用于表中字段名的映射
- `Timestamp Field`: gorm默认使用`CreatedAt``UpdatedAt`字段来跟踪数据的创建和更新日期。
上述是gorm管理实体时的默认约定但是除了默认约定外gorm也支持对实体进行自定义配置。
### gorm.Model
gorm提供了一个预先定义的实体`gorm.Model`,其中包含了常用字段:
```go
// gorm.Model definition
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
```
在自定义实体时可以将Model实体作为一个field包含在自定义实体中那么Model中定义的实体也会自动包含在自定义实体中。
上述预定义字段含义如下:
- `ID`:每行数据的唯一标识符
- `CreatedAt`:行创建时间
- `UpdatedAt`:行最后更新时间
- `DeletedAt`:用于逻辑删除
### Advanced
#### Field Level Permission
对于Exported Fields以大写开头的Field在执行CRUD时GORM默认用友所有权限。但是gorm允许通过`tag`来修改field level permission故而可以将field指定为`read-only, write-only, create-only, update-only, ignored`
> 当字段被标记为`ignored`时若使用gorm migrator创建表时`ignored fields不会被创建`。
```go
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"` // createonly (disabled read from db)
Name string `gorm:"-"` // ignore this field when write and read with struct
Name string `gorm:"-:all"` // ignore this field when write, read and migrate with struct
Name string `gorm:"-:migration"` // ignore this field when migrate with struct
}
```
#### CreatedAt / UpdatedAt
gorm默认使用CreatedAt/UpdatedAt来跟踪record创建和更新时间如果这些字段被定义将会在创建/更新操作时设置这些字段。
如果想要为Create/Update字段指定不同的名称可以为自定义字段指定`autoCreateTime``autoUpdateTime` tag。
如果想要为时间戳指定不同精度,可以按照如下格式进行定义:
```go
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
}
```
#### struct embedded
在gorm中如果想要嵌套类可以使用如下方式
- 将匿名struct作为field
```golang
type Author struct {
Name string
Email string
}
type Blog struct {
Author
ID int
Upvotes int32
}
// equals
type Blog struct {
ID int64
Name string
Email string
Upvotes int32
}
```
- 将非匿名struct用`gorm:"embedded"`进行标记:
```golang
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
}
```
- 除了指定`gorm:"embeded"`tag外还可以为嵌套struct指定prefix
```golang
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
}
```
#### field tags
当定义model时tag是可选的gorm支持tag如下所示。tag是大小写不敏感的更推荐使用驼峰的写法。
如果需要指定多个tags可以将多个tags根据`;`进行分隔gorm参数值的转义符为`\`字符。
<table>
<thead>
<tr>
<th>Tag Name</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td>column</td>
<td>column db name</td>
</tr>
<tr>
<td>type</td>
<td>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 <code>not null</code>, <code>size</code>, <code>autoIncrement</code>… specified database data type like <code>varbinary(8)</code> also supported, when using specified database data type, it needs to be a full database data type, for example: <code>MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT</code></td>
</tr>
<tr>
<td>serializer</td>
<td>specifies serializer for how to serialize and deserialize data into db, e.g: <code>serializer:json/gob/unixtime</code></td>
</tr>
<tr>
<td>size</td>
<td>specifies column data size/length, e.g: <code>size:256</code></td>
</tr>
<tr>
<td>primaryKey</td>
<td>specifies column as primary key</td>
</tr>
<tr>
<td>unique</td>
<td>specifies column as unique</td>
</tr>
<tr>
<td>default</td>
<td>specifies column default value</td>
</tr>
<tr>
<td>precision</td>
<td>specifies column precision</td>
</tr>
<tr>
<td>scale</td>
<td>specifies column scale</td>
</tr>
<tr>
<td>not null</td>
<td>specifies column as NOT NULL</td>
</tr>
<tr>
<td>autoIncrement</td>
<td>specifies column auto incrementable</td>
</tr>
<tr>
<td>autoIncrementIncrement</td>
<td>auto increment step, controls the interval between successive column values</td>
</tr>
<tr>
<td>embedded</td>
<td>embed the field</td>
</tr>
<tr>
<td>embeddedPrefix</td>
<td>column name prefix for embedded fields</td>
</tr>
<tr>
<td>autoCreateTime</td>
<td>track current time when creating, for <code>int</code> fields, it will track unix seconds, use value <code>nano</code>/<code>milli</code> to track unix nano/milli seconds, e.g: <code>autoCreateTime:nano</code></td>
</tr>
<tr>
<td>autoUpdateTime</td>
<td>track current time when creating/updating, for <code>int</code> fields, it will track unix seconds, use value <code>nano</code>/<code>milli</code> to track unix nano/milli seconds, e.g: <code>autoUpdateTime:milli</code></td>
</tr>
<tr>
<td>index</td>
<td>create index with options, use same name for multiple fields creates composite indexes, refer <a href="indexes.html">Indexes</a> for details</td>
</tr>
<tr>
<td>uniqueIndex</td>
<td>same as <code>index</code>, but create uniqued index</td>
</tr>
<tr>
<td>check</td>
<td>creates check constraint, eg: <code>check:age &gt; 13</code>, refer <a href="constraints.html">Constraints</a></td>
</tr>
<tr>
<td>&lt;-</td>
<td>set fields write permission, <code>&lt;-:create</code> create-only field, <code>&lt;-:update</code> update-only field, <code>&lt;-:false</code> no write permission, <code>&lt;-</code> create and update permission</td>
</tr>
<tr>
<td>-&gt;</td>
<td>set fields read permission, <code>-&gt;:false</code> no read permission</td>
</tr>
<tr>
<td>-</td>
<td>ignore this field, <code>-</code> no read/write permission, <code>-:migration</code> no migrate permission, <code>-:all</code> no read/write/migrate permission</td>
</tr>
<tr>
<td>comment</td>
<td>add comment for field when migration</td>
</tr>
</tbody></table>