Update wiki for SetColumn, Changed

Jinzhu 2020-06-30 17:32:41 +08:00
parent 20d64b11f8
commit 196c0198ca
2 changed files with 50 additions and 6 deletions

@ -429,15 +429,37 @@ func (user *User) BeforeCreate(tx *gorm.DB) error {
} }
``` ```
#### Hooks 里更新对象时可以直接对原对象进行修改 #### 更新时支持 Changed 检查某字段是否修改
修改插入到数据库的值,可以直接修改对象的值,不再需要在 `Hooks` 里执行 `SetColumn` (注意 `Hook` 方法的接受值必须为指针才能修改原对象) 在使用 `Update`, `Updates` 更新数据时,在 `BeforeUpdate`, `BeforeSave` 中可以使用 `Changed` 方法来检查某字段是否修改
```go ```go
func (user *User) BeforeUpdate(tx *gorm.DB) error { func (user *User) BeforeUpdate(tx *gorm.DB) error {
user.Age = 18 if tx.Statement.Changed("Name", "Admin") { // 如果 Name 或者 Role 被修改
tx.Statement.SetColumn("Age", 18)
}
if tx.Statement.Changed() { // 如果任意字段被修改
tx.Statement.SetColumn("Age", 18)
}
return nil return nil
} }
DB.Model(&user).Update("Name", "Jinzhu") // 更新 Name 为 Jinzhu
DB.Model(&user).Updates(map[string]interface{}{"name": "Jinzhu", "admin": false}) // 更新 Name 为 Jinzhu, Admin 更新为 false
DB.Model(&user).Updates(User{Name: "Jinzhu", Admin: false}) // 更新 Updates 中字段为非零值的字段,此时只更新 Name 为 Jinzhu
DB.Model(&user).Select("Name", "Admin").Updates(User{Name: "Jinzhu"}) // 更新 Name, Admin 字段Admin 字段将被更新为空值 (false)
DB.Model(&user).Select("Name", "Admin").Updates(map[string]interface{}{"Name": "Jinzhu"}) // 只更新 Name 为 Jinzhu, Role 不在 map 中存在,不会被更新
// 注意Changed 方法仅判断 `Update` / `Updates` 参数中的值与 `Model` 值的中的同样字段的值是否相同并且是否会被更新,如果不同并会被更新再返回 true
DB.Model(&User{ID: 1, Name: "jinzhu"}).Updates(map[string]interface{"name": "jinzhu2"}) // Changed("Name") => true
DB.Model(&User{ID: 1, Name: "jinzhu"}).Updates(map[string]interface{"name": "jinzhu"}) // Changed("Name") => false, name 值未更新
DB.Model(&User{ID: 1, Name: "jinzhu"}).Select("Admin").Updates(map[string]interface{"name": "jinzhu2", "admin": false}) // Changed("Name") => false, Name 值未被选择更新
DB.Model(&User{ID: 1, Name: "jinzhu"}).Updates(User{Name: "jinzhu2"}) // Changed("Name") => true
DB.Model(&User{ID: 1, Name: "jinzhu"}).Updates(User{Name: "jinzhu"}) // Changed("Name") => false, name 值未更新
DB.Model(&User{ID: 1, Name: "jinzhu"}).Select("Admin").Updates(User{Name: "jinzhu2"}) // Changed("Name") => false, Name 值未被选择更新
``` ```
### TableName 方法 ### TableName 方法

@ -430,15 +430,37 @@ func (user *User) BeforeCreate(tx *gorm.DB) error {
} }
``` ```
#### Hooks can modify updating value without `SetColumn` #### Use `Changed` to check fields changed or not
You can modify updating value without using `SetColumn` anymore (Note: need to declare hook methods with pointer receivers to modify its value) When updating with `Update`, `Updates`, You can use `Changed` method in Hooks `BeforeUpdate`, `BeforeSave` to check a field changed or not
```go ```go
func (user *User) BeforeUpdate(tx *gorm.DB) error { func (user *User) BeforeUpdate(tx *gorm.DB) error {
user.Age = 18 if tx.Statement.Changed("Name", "Admin") { // if Name or Role changed
tx.Statement.SetColumn("Age", 18)
}
if tx.Statement.Changed() { // if any fields changed
tx.Statement.SetColumn("Age", 18)
}
return nil return nil
} }
DB.Model(&user).Update("Name", "Jinzhu") // update field `Name` to `Jinzhu`
DB.Model(&user).Updates(map[string]interface{}{"name": "Jinzhu", "admin": false}) // update field `Name` to `Jinzhu`, `Admin` to false
DB.Model(&user).Updates(User{Name: "Jinzhu", Admin: false}) // Update none zero fields when using struct as argument, will only update `Name` to `Jinzhu`
DB.Model(&user).Select("Name", "Admin").Updates(User{Name: "Jinzhu"}) // update selected fields `Name`, `Admin``Admin` will be updated to zero value (false)
DB.Model(&user).Select("Name", "Admin").Updates(map[string]interface{}{"Name": "Jinzhu"}) // update selected fields exists in the map, will only update field `Name` to `Jinzhu`
// Attention: `Changed` will only check the field value of `Update` / `Updates` equals `Model`'s field value, it returns true if not equal and the field will be saved
DB.Model(&User{ID: 1, Name: "jinzhu"}).Updates(map[string]interface{"name": "jinzhu2"}) // Changed("Name") => true
DB.Model(&User{ID: 1, Name: "jinzhu"}).Updates(map[string]interface{"name": "jinzhu"}) // Changed("Name") => false, `Name` not changed
DB.Model(&User{ID: 1, Name: "jinzhu"}).Select("Admin").Updates(map[string]interface{"name": "jinzhu2", "admin": false}) // Changed("Name") => false, `Name` not selected to update
DB.Model(&User{ID: 1, Name: "jinzhu"}).Updates(User{Name: "jinzhu2"}) // Changed("Name") => true
DB.Model(&User{ID: 1, Name: "jinzhu"}).Updates(User{Name: "jinzhu"}) // Changed("Name") => false, `Name` not changed
DB.Model(&User{ID: 1, Name: "jinzhu"}).Select("Admin").Updates(User{Name: "jinzhu2"}) // Changed("Name") => false, `Name` not selected to update
``` ```
### TableName method ### TableName method