Gorm更新操作
更新所有字段
Save()默認會更新該對象的所有字段,即使你沒有賦值。
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
//1. 定義模型
type User struct {
gorm.Model
Name string
Age byte
Active bool
}
func main() {
//2. 連接Mysql數據庫
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. 把模型與數據庫中的表對應起來
db.AutoMigrate(&User{})
//4. 創建
//u1 := User{Name:"zisefeizhu", Age: 22, Active: true}
//db.Create(&u1)
//u2 := User{Name:" jingxing", Age: 21, Active:false}
//db.Create(&u2)
//5. 查詢
var user User
db.First(&user)
////6. 更新
user.Name = "zisefeizhu"
user.Age = 23
db.Debug().Save(&user) //默認會修改所有字段
//[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或者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, "active": false})
//// UPDATE users SET name='hello', age=18, active=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 更新時,GORM只會更新那些非零值的字段
// 對於下面的操作,不會發生任何更新,"", 0, false 都是其類型的零值
db.Model(&user).Updates(User{Name: "", Age: 0, Active: false})
db.Debug().Save(&user) //默認會修改所有字段
///[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 ]
更新選定字段
如果你想更新或忽略某些字段,你可以使用 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. 定義模型
type User struct {
gorm.Model
Name string
Age byte
Active bool
}
func main() {
//2. 連接Mysql數據庫
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. 把模型與數據庫中的表對應起來
db.AutoMigrate(&User{})
//4. 創建
//u1 := User{Name:"zisefeizhu", Age: 22, Active: true}
//db.Create(&u1)
//u2 := User{Name:" jingxing", Age: 21, Active:false}
//db.Create(&u2)
//5. 查詢
var user User
db.First(&user)
////6. 更新
user.Name = "zisefeizhu"
user.Age = 23
//db.Debug().Save(&user) //默認會修改所有字段
//db.Debug().Model(&user).Update("name","gengpan")
m1 := map[string]interface{}{
"name":"yike",
"age":22,
"active":true,
}
db.Debug().Model(&user).Updates(m1) //m1列出來的所有字段都會更新
//[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) //只更新age字段
//[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) //排除m1中的active更新其它字段
//[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 ]
}
無Hooks更新
上面的更新操作會自動運行 model 的 BeforeUpdate, AfterUpdate 方法,更新 UpdatedAt 時間戳, 在更新時保存其 Associations, 如果你不想調用這些方法,你可以使用 UpdateColumn, UpdateColumns
// 更新單個屬性,類似於 `Update`
db.Model(&user).UpdateColumn("name", "hello")
//// UPDATE users SET name='hello' WHERE id = 111;
// 更新多個屬性,類似於 `Updates`
db.Model(&user).UpdateColumns(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18 WHERE id = 111;
批量更新
批量更新時Hooks(鈎子函數)不會運行
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
使用SQL表達式更新
先查詢表中的第一條數據保存至user變量
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. 更新
//user.Name = "zisefeizhu"
//user.Age = 23
//db.Debug().Save(&user) //默認會修改所有字段
//db.Debug().Model(&user).Update("name","gengpan")
db.Model(&User{}).Update("age",gorm.Expr("age+?",2))
修改Hooks中的值
如果你想修改 BeforeUpdate, BeforeSave 等 Hooks 中更新的值,你可以使用 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)
}
}
其它更新選項
// 為 update SQL 添加其它的 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);