全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-21 8 分钟 ✍️ juanwangdev

GORM 更新钩子实现

本文介绍 GORM 中更新操作的钩子函数实现方法。

钩子方法

BeforeUpdate

在记录更新之前执行,常用于更新前的数据校验与修改。

Go
type Product struct {
    ID        uint
    Name      string
    Price     float64
    Stock     int
    UpdatedAt time.Time
}

// 更新前校验价格
func (p *Product) BeforeUpdate(tx *gorm.DB) error {
    if p.Price < 0 {
        return errors.New("价格不能为负数")
    }
    if p.Stock < 0 {
        return errors.New("库存不能为负数")
    }
    return nil
}

BeforeUpdate 返回 error 时,更新操作会被中止并回滚事务。

AfterUpdate

在记录更新之后执行,常用于记录变更日志或触发后续操作。

Go
type Account struct {
    ID      uint
    Balance float64
    Version int
}

// 更新后记录日志
func (a *Account) AfterUpdate(tx *gorm.DB) error {
    logEntry := AccountLog{
        AccountID: a.ID,
        Balance:   a.Balance,
        Action:    "updated",
        Time:      time.Now(),
    }
    return tx.Create(&logEntry).Error
}

钩子方法签名

Go
// 更新前钩子
func (model *ModelName) BeforeUpdate(tx *gorm.DB) error

// 更新后钩子
func (model *ModelName) AfterUpdate(tx *gorm.DB) error

检测字段变更

Go
func (u *User) BeforeUpdate(tx *gorm.DB) error {
    // 检查特定字段是否被更新
    if tx.Statement.Changed("Name") {
        log.Printf("用户名从 %v 改为 %v",
            tx.Statement.OldValue("Name"),
            tx.Statement.CurValue("Name"),
        )
    }

    // 检查多个字段
    if tx.Statement.Changed("Email", "Phone") {
        log.Println("联系方式已更新")
    }

    return nil
}

注意事项

  1. Updates 和 Save 方法会触发 BeforeUpdate/AfterUpdate 钩子。
  2. UpdateColumn/UpdateColumns 方法不会触发任何钩子。
  3. 批量更新时,钩子会对每条记录分别执行。
  4. tx.Statement.Changed("字段名") 可用于检测字段是否发生变更。
  5. BeforeUpdate 返回 error 会中止操作并回滚;AfterUpdate 的 error 不影响已提交的写入。

要点总结

  • BeforeUpdate在更新前执行,适合数据校验和预处理。
  • AfterUpdate在更新后执行,适合记录变更日志或触发后续操作。
  • Updates/Save方法触发钩子,UpdateColumn/UpdateColumns不触发。
  • 使用 tx.Statement.Changed() 检测特定字段是否被更新。
  • 钩子返回 error 的行为与创建钩子一致:Before 回滚,After 仅记录。

存放路径:D:\git2\jwdev\articles\GORM\进阶\钩子函数与回调机制\更新钩子实现.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 GORM 删除钩子实现
下一篇 → GORM 查询钩子实现
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库