gorm series - Update

Catalog

Gorm update operation

Update all fields

Save() updates all fields of the object by default, even if you don't have an assignment.

package main

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

//1. Define the model
type User struct {
	gorm.Model
	Name string
	Age byte
	Active bool
}

func main() {
	//2. Connect to Mysql database
	db, err := gorm.Open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		panic(err)
	}
	defer db.Close()
	//3. Match the model with the table in the database
	db.AutoMigrate(&User{})
	//4. Create
	//u1 := User{Name:"zisefeizhu", Age: 22, Active: true}
	//db.Create(&u1)
	//u2 := User{Name:" jingxing", Age: 21, Active:false}
	//db.Create(&u2)
	//5. Query
	var user User
	db.First(&user)
	////6. Update
	user.Name = "zisefeizhu"
	user.Age = 23
	db.Debug().Save(&user)  //All fields are modified by default
	//[2020-04-27 16:07:02]  [0.99ms]  UPDATE `users` SET `created_at` = '2020-04-27 16:06:17', `updated_at` = '2020-04-27 16:07:02', `deleted_at` = NULL, `name` = 'zisefeizhu', `age` = 23, `active` = true  WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1
	//[1 rows affected or returned ] 
}

Update modified fields

If you only want to Update the specified fields, you can use Update or Updates

// Update a single attribute if it changes
db.Model(&user).Update("name", "hello")
//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;

// Update individual properties based on given 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;

// Using map to update multiple attributes will only update those with changes
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;

// Using struct to update multiple properties will only update the fields that have changed and are non-zero values
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;

// Warning: when using struct update, GORM will only update those non-zero value fields
// For the following operations, no update will occur, "", 0, false are zero values of their types
db.Model(&user).Updates(User{Name: "", Age: 0, Active: false})
db.Debug().Save(&user)  //All fields are modified by default
///[2020-04-27 16:10:09]  [105.20ms]  UPDATE `users` SET `created_at` = '2020-04-27 16:06:17', `updated_at` = '2020-04-27 16:10:09', `deleted_at` = NULL, `name` = 'zisefeizhu', `age` = 23, `active` = true  WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1
//[1 rows affected or returned ]
db.Debug().Model(&user).Update("name","gengpan")
//[2020-04-27 16:10:09]  [0.99ms]  UPDATE `users` SET `name` = 'gengpan', `updated_at` = '2020-04-27 16:10:09'  WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1  
//[1 rows affected or returned ] 

Update selected fields

If you want to update or ignore some fields, you can use Select, Omit

db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "active": 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, "active": false})
//// UPDATE users SET age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
package main

import (
   "github.com/jinzhu/gorm"
   _ "github.com/jinzhu/gorm/dialects/mysql"
)

//1. Define the model
type User struct {
   gorm.Model
   Name string
   Age byte
   Active bool
}

func main() {
   //2. Connect to Mysql database
   db, err := gorm.Open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parseTime=True&loc=Local")
   if err != nil {
      panic(err)
   }
   defer db.Close()
   //3. Match the model with the table in the database
   db.AutoMigrate(&User{})
   //4. Create
   //u1 := User{Name:"zisefeizhu", Age: 22, Active: true}
   //db.Create(&u1)
   //u2 := User{Name:" jingxing", Age: 21, Active:false}
   //db.Create(&u2)
   //5. Query
   var user User
   db.First(&user)
   ////6. Update
   user.Name = "zisefeizhu"
   user.Age = 23
   //DB. Debug(). Save / / all fields will be modified by default
   //db.Debug().Model(&user).Update("name","gengpan")
   m1 := map[string]interface{}{
      "name":"yike",
      "age":22,
      "active":true,
   }
   db.Debug().Model(&user).Updates(m1)  //All fields listed in m1 are updated
   //[2020-04-27 16:17:00]  [0.99ms]  UPDATE `users` SET `active` = true, `age` = 22, `name` = 'yike', `updated_at` = '2020-04-27 16:17:00'  WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1  
   //[1 rows affected or returned ] 
   db.Debug().Model(&user).Select("age").Update(m1)  //Update age field only
   //[2020-04-27 16:17:00]  [0.97ms]  UPDATE `users` SET `age` = 22, `updated_at` = '2020-04-27 16:17:00'  WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1  
   //[0 rows affected or returned ] 
   db.Debug().Model(&user).Omit("active").Updates(m1)  //Exclude active from m1 to update other fields
   //[2020-04-27 16:17:00]  [1.01ms]  UPDATE `users` SET `age` = 22, `name` = 'yike', `updated_at` = '2020-04-27 16:17:00'  WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1  
   //[0 rows affected or returned ] 
}

No Hooks updates

The above update operation will automatically run the BeforeUpdate and afterupdate methods of the model, update the UpdatedAt timestamp, and save its Associations when updating. If you do not want to call these methods, you can use UpdateColumn and UpdateColumns

// Update individual properties, similar to ` update`
db.Model(&user).UpdateColumn("name", "hello")
//// UPDATE users SET name='hello' WHERE id = 111;

// Update multiple properties, similar to ` Updates`
db.Model(&user).UpdateColumns(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18 WHERE id = 111;

Batch update

Hooks will not run when updating in bulk

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);

// When using struct to update, only non-zero value fields will be updated. If you want to update all fields, please use map[string]interface {}
db.Model(User{}).Updates(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18;

// Use 'RowsAffected' to get the total number of update records
db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected

Update with SQL expression

First query the first data in the table and save it to the user variable

var user User
db.First(&user)
db.Model(&user).Update("age", gorm.Expr("age * ? + ?", 2, 100))
//// UPDATE `users` SET `age` = age * 2 + 100, `updated_at` = '2020-02-16 13:10:20'  WHERE `users`.`id` = 1;

db.Model(&user).Updates(map[string]interface{}{"age": gorm.Expr("age * ? + ?", 2, 100)})
//// UPDATE "users" SET "age" = age * '2' + '100', "updated_at" = '2020-02-16 13:05:51' WHERE `users`.`id` = 1;

db.Model(&user).UpdateColumn("age", gorm.Expr("age - ?", 1))
//// UPDATE "users" SET "age" = age - 1 WHERE "id" = '1';

db.Model(&user).Where("age > 10").UpdateColumn("age", gorm.Expr("age - ?", 1))
//// UPDATE "users" SET "age" = age - 1 WHERE "id" = '1' AND quantity > 10;
var user User
db.First(&user)
////6. Update
//user.Name = "zisefeizhu"
//user.Age = 23
//DB. Debug(). Save / / all fields will be modified by default
//db.Debug().Model(&user).Update("name","gengpan")
db.Model(&User{}).Update("age",gorm.Expr("age+?",2))

Modify values in Hooks

If you want to modify the updated values in before update, before save and so on, you can use 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)
  }
}

Other update options

// Add other SQL for 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);

Keywords: Go MySQL SQL github Database

Added by deft on Mon, 27 Apr 2020 18:54:52 +0300