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

gorm 中的Updates Update, Save,Create , UpdateColumn 区别与联系

在 GORM(Go 的 ORM 库)中UpdatesUpdateSaveCreateUpdateColumn等方法都用于数据的写入或更新,但它们的行为、触发的钩子(Hooks)、性能、适用场景有显著区别。以下是详细对比与联系:

一、核心方法对比表

方法用途是否触发 Hooks是否支持批量是否跳过零值是否需要主键备注
Create插入新记录BeforeCreate,AfterCreate❌(单条)
CreateInBatches批量
❌(插入所有字段)自动生成 ID
Save智能保存(存在则更新,否则插入)✅ 全部 Hooks
BeforeCreate/Update,After...
❌(单条)❌(更新所有非零字段)✅(更新时需主键)最“重”的操作,慎用
Update更新单个字段(不触发BeforeUpdate✅(可更新为零值)✅(或配合WhereUpdate("name", "new")
Updates更新多个字段⚠️仅当传 struct 时触发
map不触发
✅(配合Where✅(struct 会跳过零值;map 不会)✅(或配合Where最常用批量更新方式
UpdateColumn强制更新字段(包括零值)❌(强制更新,含零值)✅(或配合Where绕过 GORM 安全机制

二、逐个详解

1.Create
db.Create(&user)
  • 作用:插入一条新记录。
  • 特点
    • 忽略主键(自增或 UUID)
    • 插入所有字段(包括零值,如"",0
    • 触发BeforeCreate/AfterCreate
  • 不适用:已有主键的记录(可能报错或行为未定义)

2.Save
db.Save(&user) // user.Id != 0 → 更新;user.Id == 0 → 插入
  • 作用:根据主键是否存在,自动决定是INSERT还是UPDATE
  • 特点
    • 更新时会更新所有非零字段零值字段会被忽略!⚠️ 常见坑)
    • 触发完整 Hooks(BeforeCreate/BeforeUpdate等)
    • 必须有主键才能更新
  • 缺点
    • 性能差(先查?不一定,但逻辑复杂)
    • 零值字段无法更新(比如想把name改成""不行)
  • 建议:除非明确需要“智能保存”,否则避免使用

3.Update(单字段)
db.Model(&User{}).Where("id = ?", 1).Update("name", "new") // 或 db.Model(&user).Update("name", "new")
  • 作用更新单个字段
  • 特点
    • 不触发BeforeUpdate
    • 可更新为零值(如Update("age", 0)有效)
    • 必须配合Model()+Where()或已有主键
  • 适用:简单单字段更新

4.Updates(多字段)
(a)map(最常用)
db.Model(&User{}).Where("id = ?", 1).Updates(map[string]interface{}{ "name": "new", "age": 0, })
  • 不触发 Hooks
  • 不会跳过零值age: 0会被更新
  • 高效,适合批量更新
(b) 传struct
db.Model(&User{}).Where("id = ?", 1).Updates(User{Name: "new", Age: 0})
  • 会触发BeforeUpdate/AfterUpdate
  • 会跳过零值字段Age: 0被忽略!)
  • 如果想更新零值,需用指针或sql.NullInt64

💡关键区别Updates(map)vsUpdates(struct)行为完全不同!


5.UpdateColumn
db.Model(&User{}).Where("id = ?", 1).UpdateColumn("name", "")
  • 作用强制更新字段,即使值为零值
  • 不触发任何 Hooks
  • 绕过 GORM 的安全检查(如字段不存在也会拼 SQL,可能报错)
  • 批量更新零值的唯一可靠方式

⚠️ 危险!慎用,确保字段名正确

三、钩子(Hooks)触发规则总结

方法触发BeforeUpdate?
Save(&struct)
Updates(&struct{})
Updates(map[...])
Update("field", value)
UpdateColumn(...)
Create✅(BeforeCreate

核心原则:只有通过struct 实例更新且 GORM 能识别为模型操作),才会触发 Hooks

在 GORM 中,使用Updates时是否触发 Hooks(如BeforeUpdate/AfterUpdate)与是否开启事务无关,不仅看Updates的参数类型,还看Model()是否绑定了一个 struct 实例 ,传入的是map还是struct

结论:

只要用map[string]interface{}调用Updates,无论是否在事务中,都不会触发任何 Hooks。这是 GORM 的设计行为,事务不影响钩子的触发逻辑

临时跳过钩子:

使用原生 SQLSession 模式

如果模型已经定义了钩子,但某些特定操作想跳过钩子,可以:

方法一:使用Session(&gorm.Session{SkipHooks: true})

db.Session(&gorm.Session{SkipHooks: true}).Create(&user) db.Session(&gorm.Session{SkipHooks: true}).Save(&user) db.Session(&gorm.Session{SkipHooks: true}).Delete(&user)

⚠️ 注意:SkipHooks: true会跳过所有钩子(包括BeforeCreateAfterCreate等),但不会跳过AfterFind,因为AfterFind是在查询后自动调用的,与写操作无关。

方法二:使用原生 SQL(完全绕过 GORM 模型机制)

db.Exec("INSERT INTO users (name) VALUES (?)", "Alice")

这种方式不会触发任何 GORM 钩子,因为没有使用模型的 Create/Save 等方法

四、如何选择

场景推荐方法
插入新记录Create
更新部分字段(含零值),批量Updates(map)+ 手动设updated_at
更新部分字段,需触发BeforeUpdateUpdates(&struct{})(注意零值问题)
强制更新字段为零值UpdateColumn
不确定是新增还是更新避免Save,改用FirstOrCreate+ 显式更新
单字段更新Update("field", value)

五、最佳实践建议

  • 批量更新不要依赖 Hooks,显式设置updated_atupdated_by
  • 避免使用Save,除非你完全理解其零值行为
  • Updates(map)是最安全高效的批量更新方式
  • 如果BeforeUpdate只是用来设时间戳,直接在业务层赋值,比依赖钩子更可靠
  • 想更新零值?用mapUpdateColumn,别用 struct
http://www.jsqmd.com/news/512864/

相关文章:

  • AI时代,你的全球业务需要一张“会思考”的网络
  • Unity网络基础UDP客户端
  • Cortex-M3 异常处理机制的设计哲学
  • 25大数据 3-1 字符串函数
  • 102类农业害虫图像识别数据集分享(适用于YOLO系列深度学习分类检测任务)
  • 2026年厦门二手房装修公司推荐:局部改造工期短且环保材料靠谱品牌分析 - 品牌推荐
  • 从入门到精通:Kafka核心原理与实战避坑指南
  • SEO_从零开始学习SEO的完整步骤与实战方法
  • 制作微PE-Win系统盘
  • 永辉超市购物卡回收高效1分钟变现全教程 - 淘淘收小程序
  • 软件库带后台源码 v3.1
  • 基于单片机的药品分拣系统
  • 收藏!24家大模型面试实战经验(9个offer),小白/程序员入门必看
  • 使用yolov26实现目标检测
  • 2026年厦门二手房装修公司推荐:局部改造与全屋整装口碑好公司及真实案例解析 - 品牌推荐
  • 2025-2026年厦门二手房装修公司推荐:全屋整装高性价比品牌与用户真实反馈 - 品牌推荐
  • 2026年充电桩加盟品牌榜单:城市公共场站投资靠谱选择与运营避坑指南 - 品牌推荐
  • 新能源汽车车载双向OBC,PFC,LLC,V2G 双向充电桩MATLAB仿真模型及应用分析
  • java基于微信小程序的物流仓储管理系统 可视化
  • PunchoutLevel的product、shelf、Aisle的是什么
  • 京东e卡回收安全教程来袭,价格与流程全知晓 - 淘淘收小程序
  • 6.Adobe Animate遮罩动画
  • 厦门二手房装修公司如何选不踩雷?2026年靠谱推荐及免费量房设计服务 - 品牌推荐
  • STM32驱动HX711 24位ADC程序
  • SpringBoot+Vue 办公信息系统管理平台源码免费分享【适合毕设/课设/学习】Java+Vue+MySQL
  • 音叉这玩意儿在光热振动里真是妙啊,特别是用COMSOL建模的时候,玩参数就像调电子琴的旋钮。先给你们看段核心参数设置代码
  • 2026年充电桩加盟品牌推荐:县域下沉市场创业痛点解决靠谱品牌与扶持政策 - 品牌推荐
  • Dify 模型供应商下载失败解决办法
  • 从CUDA到MUSA(四):GPU架构揭秘——从Warp到Occupancy
  • 高频注入代码 增强滑膜esmo代码 HFI方波高频注入,提 高频注入代码 增强滑膜esmo代码...