GORM V2 模型定义、约定、标签

简介: GORM V2 模型定义、约定、标签

01

概念


使用 GORM 操作数据库,需要了解 GORM 的约定和字段标签提供的约束。尽量遵循 GORM 已有的约定,但是如果约定不符合需求,也可以自定义配置,从而改变已有约定,达到满足需求的目的。


02

模型定义


与使用 Go 标准库 sql 包操作数据库表相同,使用 GORM 操作数据库,也需要先声明模型,模型一般是基于 Go 语言的基础数据类型、实现了 Scanner 和 Valuer 接口的自定义类型,以及它们的指针或别名。


示例代码:

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
}


03

约定


GORM 已有约定

默认情况下,GORM 约定使用 ID 作为主键,使用结构体名的复数作为表名,字段名作为列名,使用 CreatedAt、UpdatedAt、DeletedAt时间追踪。如果约定与需求不符,可以自定义配置。


gorm.Model

GORM 定义了一个 gorm.Model 结构体,字段包括 ID、CreatedAt、UpdatedAt、DeletedAt,我们可以将它嵌入到我们自定义的结构体中,详情见 04 章节。


示例代码:

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


04

嵌入结构体


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

type User struct {
  gorm.Model
  Name         string
  Email        *string
  Age          uint8
  Birthday     *time.Time
  MemberNumber sql.NullString
}

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

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 中的字段名添加前缀。

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


05

标签


字段级别权限控制

在 GO 语言中,根据名称的首字母大小写来定义是否可被导出,GORM 使用可导出的字段进行 CRUD 时拥有全部权限,另外,GORM 可以使用标签控制字段级别的权限,可以让一个字段的权限是只读、只写、只创建、只更新和忽略该字段。


示例代码:

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 约定使用 CreatedAt、UpdatedAt 追踪创建/更新时间。如果您定义了他们,GORM 在创建/更新时会自动填充当前时间至这些字段,要使用不同名称的字段,您可以配置 autoCreateTim、autoUpdateTim 标签。


当然,你可以按照自己的需求自定义约定项。比如时间追踪默认是将为零值的创建时间CreatedAt 字段以当前时间填充,以当前时间戳秒数填充 UpdatedAt 字段,如果您想要保存 UNIX(毫/纳)秒时间戳,而不是 time,您只需简单地将 time.Time 修改为 int 即可,默认时间戳是 Unix 秒,你还可以使用标签将时间戳的单位改为纳秒或毫秒。


示例代码:

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


字段标签

标签是模型定义时的可选项,GORM 的标签不区分大小写,推荐使用驼峰式命名。我们会在后续章节中,陆续使用到 GORM 提供的字段标签。


查阅 GORM 字段标签:

https://gorm.io/zh_CN/docs/models.html#%E5%AD%97%E6%AE%B5%E6%A0%87%E7%AD%BE





目录
相关文章
|
8月前
|
Go 数据库
GORM模型与约定
GORM模型与约定
121 0
|
8月前
|
Go 数据库
gorm模型创建以及关键标签
gorm模型创建以及关键标签
120 0
|
7月前
|
数据安全/隐私保护 C++
C++ 中的类是一种用户定义的数据类型,用于表示具有相似特征和行为的对象的模板。
C++ 中的类是一种用户定义的数据类型,用于表示具有相似特征和行为的对象的模板。
|
8月前
|
数据库 索引
gorm 多态以及关联标签
gorm 多态以及关联标签
73 0
|
8月前
|
JavaScript 前端开发 编译器
TypeScript【可选属性、只读属性、额外的属性检查、函数类型、类类型、继承接口】(四)-全面详解(学习总结---从入门到深化)
TypeScript【可选属性、只读属性、额外的属性检查、函数类型、类类型、继承接口】(四)-全面详解(学习总结---从入门到深化)
82 0
|
8月前
|
存储 安全 Java
java标识符命名规范--代码格式规范--注释规范--最佳实践和禁忌--代码示例
java标识符命名规范--代码格式规范--注释规范--最佳实践和禁忌--代码示例
217 0
|
存储 Java
[初始java]——规范你的命名规则,变量的使用和注意事项,隐式转化和强制转化
[初始java]——规范你的命名规则,变量的使用和注意事项,隐式转化和强制转化
164 0
index.js:39 错误:修饰类属性失败。请确保提案类属性已启用并设置为使用松散模式。要在规范模式下将提案类属性与修饰器一起使用,请在阶段 2 中等待下一个主要版本的装饰器。 #79
index.js:39 错误:修饰类属性失败。请确保提案类属性已启用并设置为使用松散模式。要在规范模式下将提案类属性与修饰器一起使用,请在阶段 2 中等待下一个主要版本的装饰器。 #79
85 0
修饰类属性失败。请确保提案类属性已启用并设置为使用松散模式。要在规范模式下将提案类属性与修饰器一起使用,请在阶段 2 中等待下一个主要版本的装饰器。 #80
修饰类属性失败。请确保提案类属性已启用并设置为使用松散模式。要在规范模式下将提案类属性与修饰器一起使用,请在阶段 2 中等待下一个主要版本的装饰器。 #80
60 0
|
JavaScript
学习TypeScrip11(类型推论|类型别名)
如果你声明变量没有定义类型也没有赋值这时候TS会推断成any类型可以进行任何操作
99 0
学习TypeScrip11(类型推论|类型别名)