From 196c0198cac2e60882ba30442cceaff407bf432d Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Tue, 30 Jun 2020 17:32:41 +0800 Subject: [PATCH] Update wiki for SetColumn, Changed --- GORM-V2-Release-Note-Draft-CN.md | 28 +++++++++++++++++++++++++--- GORM-V2-Release-Note-Draft.md | 28 +++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/GORM-V2-Release-Note-Draft-CN.md b/GORM-V2-Release-Note-Draft-CN.md index d22b52d..a3fb2a9 100644 --- a/GORM-V2-Release-Note-Draft-CN.md +++ b/GORM-V2-Release-Note-Draft-CN.md @@ -429,15 +429,37 @@ func (user *User) BeforeCreate(tx *gorm.DB) error { } ``` -#### Hooks 里更新对象时可以直接对原对象进行修改 +#### 更新时支持 Changed 检查某字段是否修改 -修改插入到数据库的值,可以直接修改对象的值,不再需要在 `Hooks` 里执行 `SetColumn` (注意 `Hook` 方法的接受值必须为指针才能修改原对象) +在使用 `Update`, `Updates` 更新数据时,在 `BeforeUpdate`, `BeforeSave` 中可以使用 `Changed` 方法来检查某字段是否修改 ```go 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 } + +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 方法 diff --git a/GORM-V2-Release-Note-Draft.md b/GORM-V2-Release-Note-Draft.md index cead18d..39c430e 100644 --- a/GORM-V2-Release-Note-Draft.md +++ b/GORM-V2-Release-Note-Draft.md @@ -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 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 } + +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