时间也会有差错,也会出故障,它也能被撕成碎片,在一间屋子里留下一块永恒的碎屑。
——马尔克斯
目录
gorm操作的db实例
初始化表
普通查询
使用原生SQL
创建操作
修改操作
删除操作
校验是否存在
操作时忽略某属性
gorm结构体Tag
自定义列名称
使用过程中的一些坑
gorm操作的db实例
var db *gorm.DB
初始化表
- //待创建的表对应的结构体
- var tables = [] interface{}{
- &model.Customer{},
- &model.Order{},
- &model.OrderItem{},
- }
- var gdb *gorm.DB
- func Connection() *gorm.DB {
- return gdb
- }
- var conn = config.Connection()
- func InitTable() {
- err := CheckTable()
- if err != nil {
- log.Fatal( "check table err: ", err.Error())
- }
- log.Println( "check table completed!")
- }
- func CheckTable() error {
- var err error
- for _, table := range tables {
- flag := conn.HasTable(table)
- if !flag {
- err = conn.CreateTable(table).Error
- if err != nil {
- log.Fatal( "create table err: ", err.Error())
- break
- }
- log.Printf( "create table %v success.", table)
- continue
- }
- }
- return err
- }
普通查询
- func GetGroupByIDInternal(id string) (group model.MsGroup, err error) (error){
- db := config.Connection()
- return db.Where( "id = ?", id).Find(&group).Error
- }
说明:
1,model.MsGroup 是与数据库表对应的结构体,以上代码查询的就是ms_group表中的数据,
2,条件是以id查询,
3,一般在查询的最后使用.Error()来返回错误,查到的所有数据会存到Find方法的参数group这个对象中。
4,有几个参数就有几个?
使用原生SQL
- //查询
- func ListCatalogAppByProjectIdInternal(projectID string) (gc []model.MsGroupCatalogApp, err error) {
- err = config.Connection().Raw( "SELECT * FROM ms_group_catalog_app WHERE deleted_at IS NULL " +
- "AND parent_group_id IN (SELECT id FROM ms_group WHERE deleted_at IS NULL AND project_id = ?);", projectID).Find(&gc).Error
- return gc, err
- }
- //其他增删改操作
- db.Exec( "UPDATE orders SET shipped_at=? WHERE id IN (?)", time.Now, [] int64{ , , })
说明:
1,以上代码查询的是ms_group_catalog_app这个表中的数据,且按自定义需求使用自己写的SQL,
2,除过使用db.Raw("SQL语句").Find(&对象) 能执行查询SQL,也可使用
db.Raw("sql语句",变量).Scan(&存放的结构体对象)
来执行查询。
创建操作
- func CreateGroupCatalogAppInternal(data model.MsGroupCatalogApp) error {
- return config.Connection().Create(&data).Error
- }
说明:data是你要创建ms_group_catalog_app这个表的待插入记录
修改操作
- //修改所传的
- func updateReceiver(receiver *model.Receiver)error{
- return config.Connection().Model(receiver).Where( "id = ?",receiver.Id).Update(receiver).Error
- }
- //只修改表中某1列值,如只修改allow_create的值
- func UpdateClusterConfigInternal(conf model.ClusterConfig, tx *gorm.DB) error {
- if tx != nil {
- return tx.Model(&conf).Where( "cluster_id = ?", conf.ClusterID).Update( "allow_create", conf.AllowCreate).Error
- }
- return config.Connection().Model(&conf).Where( "cluster_id = ?", conf.ClusterID).Update( "allow_create", conf.AllowCreate).Error
- }
- //UPDATE cluster_config SET allow_create=conf.AllowCreate, updated_at='2019-7-26 15:34:10' WHERE cluster_id = conf.ID
- //修改多个值
- func UpdateNormsInternal(norm model.ContainerNorms, tx *gorm.DB) error {
- if tx != nil {
- return tx.Model(&norm).Where( "id = ?", norm.ID).
- Omit( "is_default", "created_at").
- Updates( map[ string] interface{}{ "cpu": norm.Cpu, "memory": norm.Memory}).Error
- }
- return config.Connection().Model(&norm).Where( "id = ?", norm.ID).
- Omit( "is_default", "created_at").
- Updates( map[ string] interface{}{ "cpu": norm.Cpu, "memory": norm.Memory}).Error
- }
- //UPDATE container_norms SET memory= norm.Memory,cpu= norm.Cpu, updated_at='2019-7-26 15:34:10' WHERE id = norm.ID
说明:使用Save()方法也能达到目的,但Save()操作的是所有列,慎用。
删除操作
- func delReceiver(id string)error{
- return config.Connection().Where( "id = ?",id).Delete(&model.Receiver{}).Error
- }
校验是否存在
- func CheckReceiverExistByName(Name string)bool{
- return config.Connection().Where( "name = ?",Name).Find(&model.Receiver{}).RecordNotFound()
- }
在查询最后使用.RecordNotFound()可直接得知该条记录是否存在,返回true则表示没有这条记录,返回false则表明该条数据已存在。
操作时忽略某属性
- func UpdateGroupInternal(group model.MsGroup, tx *gorm.DB) error {
- return config.Connection().Model(&group).Where( "id = ?", group.ID).Omit( "name", "created_at", "project_id").Save(&group).Error
- }
使用Omit方法,以上代码是修改操作,修改时将不会修改name,created_at, project_id这三项属性。
gorm结构体Tag
- type Model struct {
- ID string `gorm:"primary_key"`
- CreatedAt int64
- UpdatedAt *time.Time `json:"UpdatedAt,omitempty"`
- DeletedAt *time.Time `sql:"index" json:"-"`
- }
- type MsGroup struct {
- Model
- Name string `json:"name" gorm:"not null"`
- ProjectID string `json:"projectId" gorm:"not null"`
- Description string `json:"description"`
- Workloads []Workload `json:"workloads" gorm:"-"`
- CatalogApps []CatalogApp `json:"catalogApps" gorm:"-"`
- }
使用``来写tag,gorm的tag以gorm开头,如果属性是主键,标注gorm:"primary_key" ;如果使用了gorm:"-"则表示有关于gorm的操作时忽略这个字段,比如建表时。
常用Tag如下表:
tag名称 | 含义 |
---|---|
gorm:"primary_key" | 主键 |
gorm:"not null" | 该属性不能为空 |
gorm:"AUTO_INCREMENT" | 该属性自增 |
gorm:"size:255" | 对应的表中长度大小 |
gorm:"-" | 忽略该属性 |
gorm:"not null;unique" | 设置字段非空且唯一 |
gorm:"type:text" | 表的该列类型为text |
自定义列名称
默认情况下(不加指定tag时),建表后的列名如下:
- type User struct {
- ID uint // 列名为 `id`
- Name string // 列名为 `name`
- Birthday time.Time // 列名为 `birthday`
- CreatedAt time.Time // 列名为 `created_at`
- }
如果需要自定义列名:
- type Animal struct {
- AnimalId int64 `gorm:"column:beast_id"` // 设置列名为`beast_id`
- Birthday time.Time `gorm:"column:day_of_the_beast"` // 设置列名为`day_of_the_beast`
- Age int64 `gorm:"column:age_of_the_beast"` // 设置列名为`age_of_the_beast`
- }
即,使用`gorm:"column:name"`
使用过程中的一些坑
1,.Count()函数在特定情况下返回的记录数量不是正确的值
解决办法:调整语句,查询多次,分别查询
2,deleted_at是Model结课体的既定字段,删除记录时表的该条记录不会实际删除,而是deleted_at置为非空(删除操作时的时间),此时如果你的表结构设计的有些纰漏,那么功能就会有bug,如ID字段使用未来可能继续出现的值时。
解决办法:重新调整列功能及值,增加列
3,当对含有布尔值的结构体进行修改操作时,且修改到了这一列,那么此时使用.Update(&结构体变量)是不生效的,不生效体现为修改为true时能正常修改,修改为false时数据库中值不变。那么这种情况怎么解决?看上面列举的修改操作的几种情况就可以了。
时间也会有差错,也会出故障,它也能被撕成碎片,在一间屋子里留下一块永恒的碎屑。
——马尔克斯
目录
gorm操作的db实例
初始化表
普通查询
使用原生SQL
创建操作
修改操作
删除操作
校验是否存在
操作时忽略某属性
gorm结构体Tag
自定义列名称
使用过程中的一些坑
gorm操作的db实例
var db *gorm.DB
初始化表
- //待创建的表对应的结构体
- var tables = [] interface{}{
- &model.Customer{},
- &model.Order{},
- &model.OrderItem{},
- }
- var gdb *gorm.DB
- func Connection() *gorm.DB {
- return gdb
- }
- var conn = config.Connection()
- func InitTable() {
- err := CheckTable()
- if err != nil {
- log.Fatal( "check table err: ", err.Error())
- }
- log.Println( "check table completed!")
- }
- func CheckTable() error {
- var err error
- for _, table := range tables {
- flag := conn.HasTable(table)
- if !flag {
- err = conn.CreateTable(table).Error
- if err != nil {
- log.Fatal( "create table err: ", err.Error())
- break
- }
- log.Printf( "create table %v success.", table)
- continue
- }
- }
- return err
- }
普通查询
- func GetGroupByIDInternal(id string) (group model.MsGroup, err error) (error){
- db := config.Connection()
- return db.Where( "id = ?", id).Find(&group).Error
- }
说明:
1,model.MsGroup 是与数据库表对应的结构体,以上代码查询的就是ms_group表中的数据,
2,条件是以id查询,
3,一般在查询的最后使用.Error()来返回错误,查到的所有数据会存到Find方法的参数group这个对象中。
4,有几个参数就有几个?
使用原生SQL
- //查询
- func ListCatalogAppByProjectIdInternal(projectID string) (gc []model.MsGroupCatalogApp, err error) {
- err = config.Connection().Raw( "SELECT * FROM ms_group_catalog_app WHERE deleted_at IS NULL " +
- "AND parent_group_id IN (SELECT id FROM ms_group WHERE deleted_at IS NULL AND project_id = ?);", projectID).Find(&gc).Error
- return gc, err
- }
- //其他增删改操作
- db.Exec( "UPDATE orders SET shipped_at=? WHERE id IN (?)", time.Now, [] int64{ , , })
说明:
1,以上代码查询的是ms_group_catalog_app这个表中的数据,且按自定义需求使用自己写的SQL,
2,除过使用db.Raw("SQL语句").Find(&对象) 能执行查询SQL,也可使用
db.Raw("sql语句",变量).Scan(&存放的结构体对象)
来执行查询。
创建操作
- func CreateGroupCatalogAppInternal(data model.MsGroupCatalogApp) error {
- return config.Connection().Create(&data).Error
- }
说明:data是你要创建ms_group_catalog_app这个表的待插入记录
修改操作
- //修改所传的
- func updateReceiver(receiver *model.Receiver)error{
- return config.Connection().Model(receiver).Where( "id = ?",receiver.Id).Update(receiver).Error
- }
- //只修改表中某1列值,如只修改allow_create的值
- func UpdateClusterConfigInternal(conf model.ClusterConfig, tx *gorm.DB) error {
- if tx != nil {
- return tx.Model(&conf).Where( "cluster_id = ?", conf.ClusterID).Update( "allow_create", conf.AllowCreate).Error
- }
- return config.Connection().Model(&conf).Where( "cluster_id = ?", conf.ClusterID).Update( "allow_create", conf.AllowCreate).Error
- }
- //UPDATE cluster_config SET allow_create=conf.AllowCreate, updated_at='2019-7-26 15:34:10' WHERE cluster_id = conf.ID
- //修改多个值
- func UpdateNormsInternal(norm model.ContainerNorms, tx *gorm.DB) error {
- if tx != nil {
- return tx.Model(&norm).Where( "id = ?", norm.ID).
- Omit( "is_default", "created_at").
- Updates( map[ string] interface{}{ "cpu": norm.Cpu, "memory": norm.Memory}).Error
- }
- return config.Connection().Model(&norm).Where( "id = ?", norm.ID).
- Omit( "is_default", "created_at").
- Updates( map[ string] interface{}{ "cpu": norm.Cpu, "memory": norm.Memory}).Error
- }
- //UPDATE container_norms SET memory= norm.Memory,cpu= norm.Cpu, updated_at='2019-7-26 15:34:10' WHERE id = norm.ID
说明:使用Save()方法也能达到目的,但Save()操作的是所有列,慎用。
删除操作
- func delReceiver(id string)error{
- return config.Connection().Where( "id = ?",id).Delete(&model.Receiver{}).Error
- }
校验是否存在
- func CheckReceiverExistByName(Name string)bool{
- return config.Connection().Where( "name = ?",Name).Find(&model.Receiver{}).RecordNotFound()
- }
在查询最后使用.RecordNotFound()可直接得知该条记录是否存在,返回true则表示没有这条记录,返回false则表明该条数据已存在。
操作时忽略某属性
- func UpdateGroupInternal(group model.MsGroup, tx *gorm.DB) error {
- return config.Connection().Model(&group).Where( "id = ?", group.ID).Omit( "name", "created_at", "project_id").Save(&group).Error
- }
使用Omit方法,以上代码是修改操作,修改时将不会修改name,created_at, project_id这三项属性。
gorm结构体Tag
- type Model struct {
- ID string `gorm:"primary_key"`
- CreatedAt int64
- UpdatedAt *time.Time `json:"UpdatedAt,omitempty"`
- DeletedAt *time.Time `sql:"index" json:"-"`
- }
- type MsGroup struct {
- Model
- Name string `json:"name" gorm:"not null"`
- ProjectID string `json:"projectId" gorm:"not null"`
- Description string `json:"description"`
- Workloads []Workload `json:"workloads" gorm:"-"`
- CatalogApps []CatalogApp `json:"catalogApps" gorm:"-"`
- }
使用``来写tag,gorm的tag以gorm开头,如果属性是主键,标注gorm:"primary_key" ;如果使用了gorm:"-"则表示有关于gorm的操作时忽略这个字段,比如建表时。
常用Tag如下表:
tag名称 | 含义 |
---|---|
gorm:"primary_key" | 主键 |
gorm:"not null" | 该属性不能为空 |
gorm:"AUTO_INCREMENT" | 该属性自增 |
gorm:"size:255" | 对应的表中长度大小 |
gorm:"-" | 忽略该属性 |
gorm:"not null;unique" | 设置字段非空且唯一 |
gorm:"type:text" | 表的该列类型为text |
自定义列名称
默认情况下(不加指定tag时),建表后的列名如下:
- type User struct {
- ID uint // 列名为 `id`
- Name string // 列名为 `name`
- Birthday time.Time // 列名为 `birthday`
- CreatedAt time.Time // 列名为 `created_at`
- }
如果需要自定义列名:
- type Animal struct {
- AnimalId int64 `gorm:"column:beast_id"` // 设置列名为`beast_id`
- Birthday time.Time `gorm:"column:day_of_the_beast"` // 设置列名为`day_of_the_beast`
- Age int64 `gorm:"column:age_of_the_beast"` // 设置列名为`age_of_the_beast`
- }
即,使用`gorm:"column:name"`
使用过程中的一些坑
1,.Count()函数在特定情况下返回的记录数量不是正确的值
解决办法:调整语句,查询多次,分别查询
2,deleted_at是Model结课体的既定字段,删除记录时表的该条记录不会实际删除,而是deleted_at置为非空(删除操作时的时间),此时如果你的表结构设计的有些纰漏,那么功能就会有bug,如ID字段使用未来可能继续出现的值时。
解决办法:重新调整列功能及值,增加列
3,当对含有布尔值的结构体进行修改操作时,且修改到了这一列,那么此时使用.Update(&结构体变量)是不生效的,不生效体现为修改为true时能正常修改,修改为false时数据库中值不变。那么这种情况怎么解决?看上面列举的修改操作的几种情况就可以了。