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