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

回调链机制

GORM 通过回调链实现 CRUD 操作的可扩展性,本文解析其执行机制与注册方式。

回调链结构

回调处理器

Go
type processor struct {
    db      *DB
    before  string
    after   string
    remove  bool
    replace bool
    match   func(*DB) bool
    compile func() func(db *DB)
    fn      func(db *DB)
    name    string
}

type Callback struct {
    logger    logger.Interface
    processors []*processor
    clauses   []string // ["create", "query", "update", "delete", "row", "raw"]
}

预定义回调链

GORM 内置 5 条回调链:

回调链触发场景默认回调函数
Createdb.Create()Create、Associate、Commit
Querydb.Find()Query、Preload、AfterFind
Updatedb.Update()Update、Associate、Commit
Deletedb.Delete()Delete、Associate、Commit
Rawdb.Raw()Raw

回调执行流程

Create 回调链示例

Go
// GORM 内部注册
callback.Create().Register("gorm:begin_transaction", beginTransaction)
callback.Create().Register("gorm:before_create", beforeCreate)
callback.Create().Register("gorm:save_before_associations", saveBeforeAssociations)
callback.Create().Register("gorm:create", create)
callback.Create().Register("gorm:save_after_associations", saveAfterAssociations)
callback.Create().Register("gorm:after_create", afterCreate)
callback.Create().Register("gorm:commit_or_rollback_transaction", commitOrRollbackTransaction)

执行顺序:

Go
begin_transaction
  → before_create (调用 BeforeSave/BeforeCreate 钩子)
    → save_before_associations
      → create (执行 INSERT)
        → save_after_associations
          → after_create (调用 AfterCreate 钩子)
            → commit_or_rollback_transaction

查询回调链

Go
callback.Query().Register("gorm:query", Query)
callback.Query().Register("gorm:preload", Preload)
callback.Query().Register("gorm:after_query", AfterQuery)
  • gorm:query:执行 SELECT 并扫描结果
  • gorm:preload:处理 Preload() 关联加载
  • gorm:after_query:触发 AfterFind 钩子

自定义回调

注册回调

Go
db.Callback().Create().Register("plugin:audit_log", func(tx *gorm.DB) {
    if tx.Error != nil {
        return
    }
    log.Printf("created record: %v", tx.Statement.Dest)
})

回调排序控制

Go
// 在 gorm:create 之前执行
db.Callback().Create().Before("gorm:create").Register("plugin:validate", validate)

// 在 gorm:create 之后执行
db.Callback().Create().After("gorm:create").Register("plugin:notify", notify)

// 替换默认回调
db.Callback().Create().Replace("gorm:create", customCreate)

移除回调

text
db.Callback().Create().Remove("gorm:after_create")

注意事项

回调函数中若发生错误,必须设置 tx.Error,后续回调将跳过。

Replace 会覆盖默认回调,谨慎使用,可能导致内置功能失效。

自定义回调应使用命名空间前缀(如 plugin:)避免与内置回调冲突。

要点总结

  • GORM 通过 5 条回调链管理 CRUD 生命周期
  • 回调通过 Before/After 控制执行顺序
  • 支持 Register/Replace/Remove 动态扩展
  • 回调函数中错误处理通过设置 tx.Error 实现短路
  • 自定义回调应使用命名空间前缀避免冲突

存放路径:D:\git2\jwdev\articles\GORM\专家\源码分析与底层原理\回调链机制.md

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

← 上一篇 反射与元编程应用
下一篇 → 预编译语句原理
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

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

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