gorm系列-更新
- 作者: 飞扬跋扈的卤蛋
- 来源: 51数据库
- 2021-08-10
目录
- gorm更新操作
- 无hooks更新
- 使用sql表达式更新
- 修改hooks中的值
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=utf-8&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=utf-8&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);
推荐阅读
