GORM操作学习 | 青训营笔记

83 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

批量创建更改默认值 操作

type User struct{
    Name       string
    Email      *string
    ...
}

1. 批量创建(Create)

users:=[]model.User{
    {Name:"小红"},
    {Name:"小亮"},
    {Name:"小李"},
}
db.Create(users)             //第一种,可正常添加
db.CreateInBatches(users,2)  //第二种,batchSize参数为一次添加几条
db.Model(&model.User{}).Create([]map[string]interface{}{
    {"Name":"小红"},
    {"Name":"小亮"},         //第三种,这样添加的结果是只添加Name,不会添加其他列的默认值
    {"Name":"小李"},
})

2. 更新默认值(Update)

db.Model(&User{ID:2}).Update("Name","") //此时可以将默认值设置为空  update可更新空值!!!
db.Model(&User{ID:2}).Updates("Name","") //此时不可以将默认值设置为空,报错:调用实参过多
db.Model(&User{ID:2}).Updates(User{Name:""}) //不会将Name设置为空,但可运行,且updated_time会改变,但
s:=""
db.Model(&User{ID:2}).Updates(User{Email:&s}) //此时Email类型为*string,所以可更默认值为空值

GORM模型深入

字段级权限控制

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

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

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:"-"`  // 通过 struct 读写会忽略该字段   
Name string `gorm:"-:all"`        // 通过 struct 读写、迁移会忽略该字段   
Name string `gorm:"-:migration"`  // 通过 struct 迁移会忽略该字段 }

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

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

其中更改创建时间的函数为:

db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
  NowFunc: func() time.Time {
    return time.Now().Local()
  },
})

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

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

嵌入结构体

  1. 对于匿名字段,GORM 会将其字段包含在父结构体中,如:gorm.Model的使用

  2. 可以通过标签 embedded 将正常的结构体字段嵌入,例如:

type Author struct {
    Name  string
    Email string
}

type Blog struct {
  ID      int
  Author  Author `gorm:"embedded"`
  Upvotes int32
}
  1. 可以使用标签 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
}

字段标签及作用

标签名说明
column指定 db 列名
type列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not nullsizeautoIncrement… 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO_INCREMENT
serializer指定将数据序列化或反序列化到数据库中的序列化器, 例如: serializer:json/gob/unixtime
size定义列数据类型的大小或长度,例如 size: 256
primaryKey将列定义为主键
unique将列定义为唯一键
default定义列的默认值
precision指定列的精度
scale指定列大小
not null指定列为 NOT NULL
autoIncrement指定列为自动增长
autoIncrementIncrement自动步长,控制连续记录之间的间隔
embedded嵌套字段
embeddedPrefix嵌入字段的列名前缀
autoCreateTime创建时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,您可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoCreateTime:nano
autoUpdateTime创建/更新时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,您可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoUpdateTime:milli
index根据参数创建索引,多个字段使用相同的名称则创建复合索引,查看 索引 获取详情
uniqueIndex与 index 相同,但创建的是唯一索引
check创建检查约束,例如 check:age > 13,查看 约束 获取详情
<-设置字段写入的权限, <-:create 只创建、<-:update 只更新、<-:false 无写入权限、<- 创建和更新权限
->设置字段读的权限,->:false 无读权限
-忽略该字段,- 表示无读写,-:migration 表示无迁移权限,-:all 表示无读写迁移权限
comment迁移时为字段添加注释

笔记内容

记录了批量创建更改默认值 的操作方式,同时对GORM的模型进行了深入学习,其中包含字段级权限控制创建/更新时间追踪嵌入结构体字段标签及作用,学习资料主要来源于模型定义 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.