GORM V2 写操作

时间:2022-07-25
本文章向大家介绍GORM V2 写操作,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

01 概念

在项目开发中,数据库写操作包含新增、删除和修改,使用 GORM V2 可以更加安全和便捷进行写操作。

02 新增

普通创建 使用 GORM V2 创建记录,可以定义一个自定义结构体类型的变量,调用 Create 方法,通过入参结构体类型变量的指针来创建记录。

stu := Student{
  Name:  "rose",
  Age:   28,
  Email: "rose@88.com",
}
result := gormDB.Create(&stu)

通过获取变量的 ID,可以得到插入记录的主键 ID。

insertID := stu.ID
fmt.Printf("主键 ID:%dn", insertID)

通过调用 Error 和 RowsAffected,可以分别获取插入错误和插入行数。

insertErr := result.Error
fmt.Printf("插入错误:%vn", insertErr)
num := result.RowsAffected
fmt.Printf("影响行数:%dn", num)

GORM V2 新增了选定字段和排除字段创建

选定字段创建 Select

gormDB.Select("Name", "Age").Create(&stu)

排除字段创建 Omit

gormDB.Omit("Age", "Email").Create(&stu)

批量创建 定义一个切片变量,通过调用 Create 方法,入参切片类型的变量,GORM 会生成一个单一的 sql 语句来插入所有数据,并回填主键的值。

stus := []Student{
  {    
    Name: "coco",    
    Age: 19,    
    Email: "coco@88.com",  
   },  
   {    
    Name: "bear",    
    Age: 12,    
    Email: "bear@88.com",  
   },
 }
 gormDB.Create(&stus)
 for _, stu := range stus {  
   fmt.Printf("ID:%dn", stu.ID)
 }

GORM 支持根据 map 创建记录 根据 map 单条创建

stuMap := map[string]interface{}{
  "Name": "name1", 
   "Age": 22,  
   "Email": "name1@8.com",
 }
 gormDB.Model(&Student{}).Create(stuMap)

根据 map 批量创建

stusMap := []map[string]interface{}{
  {    
    "Name": "apple",    
    "Age": 20,    
    "Email": "apple@88.com",
  },  
  {    
    "Name": "pear", 
    "Age": 21,   
    "Email": "pear@88.com",  
  },
}
gormDB.Model(&Student{}).Create(stusMap)

需要注意的是,根据 map 创建,不会自动填充 gorm.Model 结构体定义的字段。

默认值

可以使用 GORM 标签 default 设置默认值,插入数据时,设置的默认值会被用于填充值为零值的字段。

需要注意的是,如果默认值本身是数据类型的零值,将不会被保存到数据库。对于数据库表的设置默认值的字段,需要预先在声明模型的 struct 字段上使用标签 default 设置默认值,否则会插入该字段数据类型的零值。

03 删除

单条删除 删除单条记录,删除对象需要指定主键,否则会触发批量删除并且会被阻止全局删除功能拦截。

stu := Student{}
stu.ID = 16
gormDB.Delete(&stu)

根据主键删除

GORM 支持根据内联条件指定删除对象的主键,但是只支持数据类型为整型主键。

gormDB.Delete(&Student{}, 2)
gormDB.Delete(&Student{}, "2")
gormDB.Delete(&Student{},[]int{8,9})

批量删除

GORM 可以根据指定的删除条件,批量删除全部匹配的记录。

gormDB.Where("email LIKE ?", "%88%").Delete(Student{})
gormDB.Delete(Student{}, "email LIKE ?", "%88%")

阻止全局删除 如果没有指定 WHERE 条件,GORM 不会执行删除操作,并返回 ErrMissingWhereClause 错误。

如果想要全局删除,必须指定 WHERE 条件,或者执行原生 SQL,或者启用 AllowGlobalUpdate 模式。

软删除

如果模型包含 gorm.DeletedAt 字段,将会启用软删除,软删除是指不会真的删除记录,而是会将 DeletedAt 字段设置为当前时间,并且被软删除的记录,不可以通过正常查询操作获取。

如果需要查询被软删除的记录,需要使用 Unscoped 方法。

永久删除 永久删除记录,也需要使用 Unscoped 方法。

gormDB.Unscoped().Where("id = ?", 5).Delete(&Student{})
gormDB.Unscoped().Where("id IN ?", []int{8,9}).Delete(&Student{})

04 修改

保存所有字段

调用 Save 方法更新数据,会保存所有字段,即使字段的值为字段类型的零值。

student := Student{}
gormDB.First(&student)
student.Name="cat1"
student.Age=0
student.Email="cat1@88.com"
gormDB.Save(&student)

更新单个列

使用 Update 方法更新单个列时,需要指定条件,否则会返回 ErrMissingWhereClause 的错误。

student := Student{}
student.ID = 15
gormDB.Model(&student).Update("email", "cat@gmail.com")
gormDB.Model(&Student{}).Where("age = ?", 19).Update("age", 21)

当使用 Model 方法时,并且该对象的主键有值,该值会被用于更新条件。

student := Student{}
student.ID = 15
gormDB.Model(&student).Where("email = ?", "cat@gmail.com").Update("name", "bigFace")

更新多个列

使用 Updates 方法更新多个列,GORM 支持 struct 和 map[string]interface{} 参数,需要注意的是,当使用 struct 作为参数时,GORM 只会更新字段的值不是字段类型的零值的字段。

struct

student := Student{}
student.ID = 1
gormDB.Model(&student).Updates(Student{Name: "book", Age: 20})

map

student := Student{}
student.ID = 15
gormDB.Model(&student).Updates(map[string]interface{}{"name" : "panda", "age": 30})

更新选定或排除字段

更新操作,也支持根据选定或排除字段进行更新。

选定字段 Select

student := Student{}
student.ID = 2
gormDB.Model(&student).Select("name").Updates(map[string]interface{}{"name":"lucy", "email":"lucy@88.com"})

排除字段 Omit

student := Student{}
student.ID = 3
gormDB.Model(&student).Omit("name").Updates(map[string]interface{}{"name": "dog", "age": 29, "email":"dog@gmail.com"})

批量更新

如果未通过 Model 方法指定记录的主键,GORM 则会执行批量更新。

struct

gormDB.Model(&Student{}).Where("name=?", "milk").Updates(Student{Name: "tom", Age: 18})

map

gormDB.Model(&Student{}).Where("name = ?", "frank").Updates(map[string]interface{}{"name":"milk", "email": "milk@88.com"})
gormDB.Table("students").Where("name = ?", "tom").Updates(map[string]interface{}{"name":"honey", "email" :"honey@88.com"})

阻止全局更新

如果未指定任何条件执行批量更新,默认情况下,GORM 不会执行该操作,并且会返回 ErrMissingWhereClause 错误。

如果希望执行全局更新,需要指定条件,或使用原生 SQL,或启用 AllowGlobalUpdate 模式。

更新的记录数和更新操作的错误

获取受影响的行数和更新操作的错误。

result := gormDB.Table("students").Where("name = ?", "honey").Updates(map[string]interface{}{"name":"life", "email" :"life@88.com"})
rows := result.RowsAffected
fmt.Printf("更新的记录数:%dn", rows)
fmt.Println(result.Error)