更新
更新所有字段
Save会更新所有字段,即使你没有赋值。
db.First(&user) user.Name = "qimi" user.Age = 99 db.Save(&user) // save是更新所有字段 // UPDATE `users` SET `created_at` = '2020-02-16 12:52:20',`updated_at` = '2020-02-16 12:54:23'
更新修改字段
// 更新单个属性,如果它有变化
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,"actives":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更新时,GORM只会更新那些非零的字段
// 对于下面的操作,不会发生任何更新,"",0,false 都是其类型的零值。
db.Model(&user).Updates(User{Name:"",Age:0,Actived:fale})更新选定字段
如果想更新或忽略某些字段,可以使用Select,Omit
db.Model(&user).Select("name").Updates(map[string]interface{}{"name":""hello,"age":18,"actived":true})
// 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;无Hooks更新
上面的更新操作会自动运行model的BeforeUpdate,AfterUpdate方法,更新UpateAt时间戳,在更新时保存其Associationd,如果你不想调用这些方法,你可以使用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:28})
// UPDATE users SET name='hello', age=28 WHERE id=111;批量更新
批量更新时Hooks(钩子函数)不会运行。
fb.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 `user`
// 更新多个
db.Model(&users).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`
// 更新指定的列
db.Model(&user).UpdateColumn("age", gorm.Expr("age - ?",1))
// UPDATE "users" SET "age" = age - 1 WHERE "id" = '1';
// 更新id是1同时年龄大鱼10
db.Model(&user).Where("age > 10").UpdateColumn("age", gorm.Expr("age - ?",1))
// UPDATE "users" SET "age" = age - 1 WHERE "id" = '1' AND quantity >10;
例子:让users表中多有的用户的年龄在原来的基础上+2
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 FOE UNKNOWN) ;