这是我参与「第五届青训营 」伴学笔记创作活动的第 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 约定使用 CreatedAt、UpdatedAt 追踪创建/更新时间。如果定义了这种字段,GORM 在创建、更新时会自动填充当前时间
其中更改创建时间的函数为:
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
NowFunc: func() time.Time {
return time.Now().Local()
},
})
要使用不同名称的字段,可以配置 autoCreateTime、autoUpdateTime 标签
如果要保存 UNIX(毫/纳)秒时间戳,而不是 time,只需将 time.Time 修改为 int 即可
嵌入结构体
-
对于匿名字段,GORM 会将其字段包含在父结构体中,如:gorm.Model的使用
-
可以通过标签
embedded将正常的结构体字段嵌入,例如:
type Author struct {
Name string
Email string
}
type Blog struct {
ID int
Author Author `gorm:"embedded"`
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
}
字段标签及作用
| 标签名 | 说明 |
|---|---|
| column | 指定 db 列名 |
| type | 列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not null、size, autoIncrement… 像 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.