## 更新 ### 1. 更新全部字段 `Save`将包括执行更新SQL时的所有字段,即使它没有更改 ~~~ 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`,`Updates` ~~~ // 更新单个属性(如果更改) db.Model(&user).Update("name", "hello") //// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111; // 使用组合条件更新单个属性 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; // 使用`map`更新多个属性,只会更新这些更改的字段 db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false}) //// UPDATE users SET name='hello', age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111; // 使用`struct`更新多个属性,只会更新这些更改的和非空白字段 db.Model(&user).Updates(User{Name: "hello", Age: 18}) //// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111; // 警告:当使用struct更新时,FORM将仅更新具有非空值的字段 // 对于下面的更新,什么都不会更新为"",0,false是其类型的空白值 db.Model(&user).Updates(User{Name: "", Age: 0, Actived: false}) ~~~ ### 3. 更新选择的字段 如果您只想在更新时更新或忽略某些字段,可以使用`Select`,`Omit` ~~~ db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false}) //// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111; db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false}) //// UPDATE users SET age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111; ~~~ ### 4. 更新更改字段但不进行Callbacks 以上更新操作将执行模型的`BeforeUpdate`,`AfterUpdate`方法,更新其`UpdatedAt`时间戳,在更新时保存它的`Associations`,如果不想调用它们,可以使用`UpdateColumn`,`UpdateColumns` ~~~ // 更新单个属性,类似于`Update` db.Model(&user).UpdateColumn("name", "hello") //// UPDATE users SET name='hello' WHERE id = 111; // 更新多个属性,与“更新”类似 db.Model(&user).UpdateColumns(User{Name: "hello", Age: 18}) //// UPDATE users SET name='hello', age=18 WHERE id = 111; ~~~ ### 5. Batch Updates 批量更新 `Callbacks`在批量更新时不会运行 ~~~ db.Table("users").Where("id IN (?)", []int{10, 11}).Updates(map[string]interface{}{"name": "hello", "age": 18}) //// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11); // 使用struct更新仅适用于非零值,或使用map[string]interface{} db.Model(User{}).Updates(User{Name: "hello", Age: 18}) //// UPDATE users SET name='hello', age=18; // 使用`RowsAffected`获取更新记录计数 db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected ~~~ ### 6. 使用SQL表达式更新 ~~~ DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100)) //// UPDATE "products" SET "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2'; DB.Model(&product).Updates(map[string]interface{}{"price": gorm.Expr("price * ? + ?", 2, 100)}) //// UPDATE "products" SET "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2'; DB.Model(&product).UpdateColumn("quantity", gorm.Expr("quantity - ?", 1)) //// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = '2'; DB.Model(&product).Where("quantity > 1").UpdateColumn("quantity", gorm.Expr("quantity - ?", 1)) //// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = '2' AND quantity > 1; ~~~ ### 7. 在Callbacks中更改更新值 如果要使用`BeforeUpdate`,`BeforeSave`更改回调中的更新值,可以使用`scope.SetColumn`,例如 ~~~ func (user *User) BeforeSave(scope *gorm.Scope) (err error) { if pw, err := bcrypt.GenerateFromPassword(user.Password, 0); err == nil { scope.SetColumn("EncryptedPassword", pw) } } ~~~ ### 8. 额外更新选项 ~~~ // 为Update语句添加额外的SQL选项 db.Model(&user).Set("gorm:update_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Update("name, "hello") //// UPDATE users SET name='hello', updated_at = '2013-11-17 21:34:10' WHERE id=111 OPTION (OPTIMIZE FOR UNKNOWN); ~~~