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

GORM 删除钩子实现

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

钩子方法

BeforeDelete

在记录删除之前执行,常用于删除前的校验和关联数据处理。

Go
type Order struct {
    ID     uint
    UserID uint
    Status string
}

// 删除前校验订单状态
func (o *Order) BeforeDelete(tx *gorm.DB) error {
    if o.Status == "paid" {
        return errors.New("已支付订单不能删除")
    }
    return nil
}

BeforeDelete 返回 error 时,删除操作会被中止并回滚事务。

AfterDelete

在记录删除之后执行,常用于清理关联数据或记录删除日志。

Go
type User struct {
    ID   uint
    Name string
}

// 删除后清理关联数据
func (u *User) AfterDelete(tx *gorm.DB) error {
    // 清理关联订单
    err := tx.Where("user_id = ?", u.ID).Delete(&Order{}).Error
    if err != nil {
        return err
    }

    // 记录删除日志
    log.Printf("用户 %d (%s) 已被删除", u.ID, u.Name)
    return nil
}

钩子方法签名

Go
// 删除前钩子
func (model *ModelName) BeforeDelete(tx *gorm.DB) error

// 删除后钩子
func (model *ModelName) AfterDelete(tx *gorm.DB) error

软删除与钩子

Go
type Post struct {
    ID        uint
    Title     string
    DeletedAt gorm.DeletedAt `gorm:"index"`
}

// 软删除时同样触发钩子
func (p *Post) BeforeDelete(tx *gorm.DB) error {
    // 软删除前校验
    if p.Title == "" {
        return errors.New("标题为空的帖子不能删除")
    }
    return nil
}

func (p *Post) AfterDelete(tx *gorm.DB) error {
    // 软删除后更新缓存
    return clearPostCache(p.ID)
}

使用 gorm.DeletedAt 字段时,Delete 方法执行的是软删除,钩子同样会被触发。

注意事项

  1. Delete 方法触发 BeforeDelete/AfterDelete 钩子。
  2. 批量删除时,钩子会对每条记录分别执行(若逐条删除)。
  3. db.Unscoped().Delete() 执行硬删除,同样触发钩子。
  4. BeforeDelete 返回 error 会中止并回滚;AfterDelete 返回 error 仅记录日志(软删除已生效)。
  5. 关联删除(如 Select/Constraint)不触发关联模型的删除钩子,仅在模型自身调用 Delete 时触发。

要点总结

  • BeforeDelete在删除前执行,适合权限校验和业务规则检查。
  • AfterDelete在删除后执行,适合清理关联数据或记录日志。
  • 软删除(DeletedAt)和硬删除(Unscoped)都会触发删除钩子。
  • 批量删除时钩子逐条执行,需注意性能影响。
  • 关联级联删除不会触发关联模型的删除钩子,仅主模型钩子生效。

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

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

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

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

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