Update README for Updating

This commit is contained in:
Jinzhu 2016-02-19 11:23:08 +08:00
parent 2786ab34b4
commit e7c4e7de4e
1 changed files with 71 additions and 26 deletions

View File

@ -47,9 +47,14 @@ go get -u github.com/jinzhu/gorm
- [Query Chains](#query-chains)
- [Preloading (Eager loading)](#preloading-eager-loading)
- [Update](#update)
- [Update Without Callbacks](#update-without-callbacks)
- [Update All Fields](#update-all-fields)
- [Update Changed Fields](#update-changed-fields)
- [Update Selected Fields](#update-selected-fields)
- [Update Changed Fields Without Callbacks](#update-changed-fields-without-callbacks)
- [Batch Updates](#batch-updates)
- [Update with SQL Expression](#update-with-sql-expression)
- [Change Updating Values In Callbacks](#change-updating-values-in-callbacks)
- [Extra Update option](#extra-update-option)
- [Delete](#delete)
- [Batch Delete](#batch-delete)
- [Soft Delete](#soft-delete)
@ -453,66 +458,86 @@ db.Preload("Orders", "state = ?", "paid").Preload("Orders.OrderItems").Find(&use
## Update
### Update All Fields
`Save` will include all fields when perform the Updating SQL, even it is not changed
```go
// Update an existing struct
db.First(&user)
user.Name = "jinzhu 2"
user.Age = 100
db.Save(&user)
//// UPDATE users SET name='jinzhu 2', age=100, updated_at = '2013-11-17 21:34:10' WHERE id=111;
db.Where("active = ?", true).Save(&user)
//// UPDATE users SET name='jinzhu 2', age=100, updated_at = '2013-11-17 21:34:10' WHERE id=111 AND active = true;
//// UPDATE users SET name='jinzhu 2', age=100, birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111;
```
// Update an attribute if it is changed
### Update Changed Fields
If you only want to update changed Fields, you could use `Update`, `Updates`
```go
// Update single attribute if it is changed
db.Model(&user).Update("name", "hello")
//// UPDATE users SET name='hello', updated_at = '2013-11-17 21:34:10' WHERE id=111;
//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
// Update single attribute with combined conditions
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;
//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;
db.First(&user, 111).Update("name", "hello")
//// SELECT * FROM users LIMIT 1;
//// UPDATE users SET name='hello', updated_at = '2013-11-17 21:34:10' WHERE id=111;
// Update multiple attributes if they are changed
// Update multiple attributes with `map`, will only update those changed fields
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;
// Update multiple attributes if they are changed (update with struct only works with none zero values)
// Update multiple attributes with `struct`, will only update those changed & non blank fields
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;
// Add extra SQL option for updating 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);
// WARNING when update with struct, GORM will only update those fields that with non blank value
// For below Update, nothing will be updated as "", 0, false are blank values of their types
db.Model(&user).Updates(User{Name: "", Age: 0, Actived: false})
```
### Update Without Callbacks
### Update Selected Fields
By default, update will call BeforeUpdate, AfterUpdate callbacks, if you want to update w/o callbacks and w/o saving associations:
If you only want to update or ignore some fields when updating, you could use `Select`, `Omit`
```go
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;
```
### Update Changed Fields Without Callbacks
Updating operations above will invoke `BeforeUpdate`, `AfterUpdate`, Update UpdatedAt timestamp, Save Associations callbacks, if you don't call them, you could use `UpdateColumn`, `UpdateColumns`
```go
// Update single attribute, similar with `Update`
db.Model(&user).UpdateColumn("name", "hello")
//// UPDATE users SET name='hello' WHERE id = 111;
// Update with struct only works with none zero values, or use map[string]interface{}
// Update multiple attributes, similar with `Updates`
db.Model(&user).UpdateColumns(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18 WHERE id = 111;
```
### Batch Updates
Callbacks won't run when do batch updates
```go
db.Table("users").Where("id = ?", 10).Updates(map[string]interface{}{"name": "hello", "age": 18})
//// UPDATE users SET name='hello', age=18 WHERE id = 10;
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);
// Update with struct only works with none zero values, or use map[string]interface{}
db.Model(User{}).Updates(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18;
// Callbacks won't run when do batch updates
// Use `RowsAffected` to get the count of affected records
// Get updated records count with `RowsAffected`
db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected
```
@ -520,10 +545,10 @@ db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected
```go
DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
//// UPDATE "products" SET "code" = 'L1212', "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2';
//// 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 "code" = 'L1212', "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2';
//// 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';
@ -532,6 +557,26 @@ DB.Model(&product).Where("quantity > 1").UpdateColumn("quantity", gorm.Expr("qua
//// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = '2' AND quantity > 1;
```
### Change Updating Values In Callbacks
If you want to change updating values in callbacks using `BeforeUpdate`, `BeforeSave`, you could use `scope.SetColumn`, for example:
```go
func (user *User) BeforeSave(scope *gorm.Scope) (err error) {
if pw, err := bcrypt.GenerateFromPassword(user.Password, 0); err == nil {
scope.SetColumn("EncryptedPassword", pw)
}
}
```
### Extra Update option
```go
// Add extra SQL option for updating 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);
```
## Delete
```go