文章目录
1. 场景:
- 在配置某一个参数时,假如该参数为bool类型。在从“ture"切换到”false"时发现数据库中没有更换过来
- 删除一个策略的描述信息时,发现修改失败,描述依然存在
这种情况基本上是由于一个原因导致的:Gorm使用Updates更新数据库操作时,只会更新非零字段。
在Go中0值的说明:
类型 | 对应的0值 |
---|---|
string | “” |
int,uint类 | 0 |
bool | false |
2. Gorm中更新操作说明
更新操作包括:
- 更新全部字段
- 更新单列
- 更新多列
- 更新选定字段
1)更新全部字段: save
使用save
方法保存所有的字段,即使是零值字段。
db.First(&user)
user.Name = "jinzhu 2"
user.Age = 100
db.Save(&user)
// UPDATE users SET name='jinzhu 2', age=100, birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111;
2)更新单列字段:update
当使用 Update
更新单个列时,你需要指定条件,否则会返回 ErrMissingWhereClause
错误。当使用了 Model
方法,且该对象主键有值,该值会被用于构建条件;如果同时存在where
条件,则两个需要同时满足,例如:
/ 条件更新
db.Model(&User{}).Where("active = ?", true).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE active=true;
// User 的 ID 是 `111`
db.Model(&user).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
// 根据条件和 model 的值进行更新
db.Model(&user).Where("active = ?", true).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;
3)更新多列字段:updates
Updates
方法支持struct
和map[string]interface{}
参数。当使用struct
更新时,默认情况下,GORM 只会更新非零值的字段。
????????????从这里可以看出:
当通过 struct 更新时,GORM 只会更新非零字段。 如果您想确保指定字段被更新,你应该使用 Select
更新选定字段,或使用 map
来完成更新操作
// 根据 `struct` 更新属性,只会更新非零值的字段
db.Model(&user).Updates(User{Name: "hello", Age: 18, Active: false})
// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;
// 根据 `map` 更新属性
db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false})
// UPDATE users SET name='hello', age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
// 使用`select`更新指定字段, 无论是否存在零值 ????????????
db.Select("name", "desc", "class").Where(&user).Updates(users)
????: github中有一个库专门用于将struct
转换为map[string]interface
,不再需要我们自己构建map对象。可以通过go get github.com/fatih/structs
进行安装
4)更新选定字段: select
,omit
如果您想要在更新时选定、忽略某些字段,您可以使用 Select
、Omit
。
-
????
select
用来选择某些字段 -
????**
omit
用来排除某些字段**。常见的用法:db.Select("*").Omit("id").Update()
// 使用 Map 进行 Select
// User's ID is `111`:
db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false})
// UPDATE users SET name='hello' WHERE id=111;
db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false})
// UPDATE users SET age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
// 使用 Struct 进行 Select(会 select 零值的字段)
db.Model(&user).Select("Name", "Age").Updates(User{Name: "new_name", Age: 0})
// UPDATE users SET name='new_name', age=0 WHERE id=111;
// Select 所有字段(查询包括零值字段的所有字段)
db.Model(&user).Select("*").Update(User{Name: "jinzhu", Role: "admin", Age: 0})
// Select 除 Role 外的所有字段(包括零值字段的所有字段)
db.Model(&user).Select("*").Omit("Role").Update(User{Name: "jinzhu", Role: "admin", Age: 0})