当前位置: 首页 > news >正文

Gorm(三)更新操作

在 Gorm 中,SaveUpdatesUpdateColumn 是用于更新数据的核心方法,它们的行为和适用场景不同,以下是详细说明:

一、Save:全字段更新(包含零值)

Save 会根据记录的主键(如 ID)更新整条记录,包含所有字段(即使字段为零值或未修改),适用于需要全量覆盖的场景。

基本用法
// 1. 先查询出要更新的记录(确保主键存在)
var user User
db.First(&user, 1) // 查询 ID=1 的用户// 2. 修改字段(包括部分字段)
user.Name = "Alice Updated"
user.Age = 0 // 零值也会被更新// 3. 全字段更新
result := db.Save(&user)// 结果查看
fmt.Println("影响行数:", result.RowsAffected) // 1(成功更新)
fmt.Println("错误:", result.Error)
特性
  • 基于主键更新:必须确保结构体中包含主键(如 ID),否则会被视为插入操作(INSERT)。
  • 更新所有字段:无论字段是否有变化,都会被写入数据库(包括 0"" 等零值)。
  • 触发钩子:会执行 BeforeSaveAfterSave 等钩子函数(如果定义)。
  • 自动更新 UpdatedAt:无需手动设置,Save 会自动更新该字段。

二、Updates:部分字段更新(忽略零值,支持 struct/map)

Updates 用于更新部分字段,默认忽略零值(仅更新非零字段),支持通过结构体或 map 指定更新内容,更灵活高效。

1. 通过结构体更新(忽略零值)
// 更新 ID=1 的用户,仅更新非零字段
result := db.Model(&User{}).Where("id = ?", 1).Updates(User{Name: "Bob Updated", // 非零值,会被更新Age:  0,             // 零值,默认被忽略(不会更新 age 字段)
})
// SQL: UPDATE users SET name='Bob Updated', updated_at='2024-05-01' WHERE id=1

注意

  • 结构体中零值字段会被忽略(如需强制更新零值,需用 mapSelect 指定字段)。
  • 需通过 ModelWhere 指定更新条件(否则可能更新全表,非常危险)。
2. 通过 map 更新(包含零值)

map[string]interface{} 可以强制更新零值,适合需要更新零值或动态字段的场景:

// 使用 map 更新,零值会被执行
result := db.Model(&User{}).Where("id = ?", 1).Updates(map[string]interface{}{"name": "Charlie Updated","age":  0, // 零值会被更新到数据库
})
// SQL: UPDATE users SET name='Charlie Updated', age=0, updated_at='2024-05-01' WHERE id=1
3. 强制更新指定字段(包括零值)

如果用结构体更新时需要包含零值,可通过 Select 显式指定字段:

// 强制更新 name 和 age(即使 age 是零值)
result := db.Model(&User{}).Where("id = ?", 1).Select("name", "age").Updates(User{Name: "Dave Updated",Age:  0, // 被 Select 指定,会更新
})
特性
  • 部分更新:只更新指定的非零字段(结构体)或所有键值对(map),效率更高。
  • 条件更新:必须通过 WhereModel(含主键)指定条件,避免全表更新。
  • 触发钩子:会执行 BeforeUpdateAfterUpdate 等钩子函数。
  • 自动更新 UpdatedAt:同 Save

三、UpdateColumn / UpdateColumns:绕过钩子的字段更新

UpdateColumn(单字段)和 UpdateColumns(多字段)用于直接更新字段,不触发任何钩子函数,也不会自动更新 UpdatedAt,适合需要高性能或跳过业务逻辑的场景。

1. UpdateColumn:更新单个字段
// 更新 ID=1 的用户的 name 字段,不触发钩子,不更新 UpdatedAt
result := db.Model(&User{}).Where("id = ?", 1).UpdateColumn("name", "Eve Updated")
// SQL: UPDATE users SET name='Eve Updated' WHERE id=1
2. UpdateColumns:更新多个字段
// 更新多个字段,同样绕过钩子
result := db.Model(&User{}).Where("id = ?", 1).UpdateColumns(map[string]interface{}{"name": "Frank Updated","age":  30,
})
// SQL: UPDATE users SET name='Frank Updated', age=30 WHERE id=1
特性
  • 无钩子:不执行 BeforeUpdateAfterUpdate 等钩子,适合纯数据更新。
  • 不更新 UpdatedAt:需手动指定才会更新该字段(如 UpdateColumns(map[string]interface{}{"updated_at": time.Now()}))。
  • 高效:减少额外逻辑处理,性能优于 SaveUpdates
  • 支持条件和表达式:可结合 Where 或 SQL 表达式(如自增):
    // 年龄自增 1
    db.Model(&User{}).Where("id = ?", 1).UpdateColumn("age", gorm.Expr("age + 1"))
    

对比与适用场景

方法更新范围零值处理触发钩子更新 UpdatedAt适用场景
Save全字段(基于主键)包含零值全量覆盖更新(如完整编辑)
Updates部分字段(struct/map)结构体忽略零值,map 包含常规部分更新(如修改部分属性)
UpdateColumn单个/多个字段包含零值高性能更新、跳过业务逻辑

注意事项

  • 更新条件:使用 UpdatesUpdateColumn 时,务必通过 WhereModel(含主键)指定条件,否则可能导致全表更新(极其危险)。
  • 结构体 vs map:结构体更新简洁但忽略零值,map 可强制更新零值,按需选择。
  • 钩子影响:如果业务逻辑依赖钩子(如数据校验、日志记录),避免使用 UpdateColumn

根据更新需求(全量/部分、是否触发钩子、是否包含零值)选择合适的方法,可确保代码高效且符合业务逻辑。

http://www.dtcms.com/a/533828.html

相关文章:

  • 新乡微信网站建设wordpress仿安卓主题下载
  • 佛山自助建站软件咖啡网站建设的优势
  • 佛山网站架设360线上推广
  • 网站留言效果怎么做钦州建设银行社招聘网站
  • 浙江建设信息港网站查询开网店如何运营和推广
  • XML 查看
  • 广州网站建设制作wordpress分页上一页
  • 怎么做好邯郸网站建设风铃微网站怎么做
  • 网站建设对标行业分析建设行业的门户网站
  • 城乡住房建设部网站保证金wordpress系统api
  • SZU大学物理1实验报告|电源设计
  • SAP 在生产机维护需传输请求的表
  • 小广告怎么制作seo搜索引擎官网
  • 【Linux kali 更换yum源】
  • huggingface/trl的单卡训练reward model示例
  • 智慧校园集控管理平台解决方案PPT(39页)
  • 网站开发宣传语旅游产品设计方案
  • 东坑网站建设合肥电脑培训
  • 哪些网站做家政推广手机排版软件app
  • 【关于导线的学习】
  • muse cc 做网站贵阳网站建设优化
  • wordpress 企业主体苏州seo服务
  • 怎么查网站外链数微商城系统源码
  • 网站建设方案策划书前言网站建设一个月做十单
  • linux创建网站网站设计行业前景
  • 数字权益市场爆发:如何通过权益数卡选对优质货源
  • 电影网站怎么做优化网站设计项目书
  • 呼市做网站微站网
  • 濮阳做网站的公司有哪些一级a做爰片2202网站
  • 济南专业做网站公司汕头seo网站推广费用