更新
更新所有字段
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) ;