InfoSphere/GORM 中文版/ 返回书籍
Advanced Topics

编写插件

qianmoQqianmoQ· 更新于 2026-09-16· 阅读 9 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

回调

GORM 通过 回调 驱动其核心功能。这些回调为 创建查询更新删除原生SQL 等各种数据库操作提供了钩子,允许对 GORM 的行为进行广泛定制。

回调注册在全局的 *gorm.DB 层级,而不是基于会话。这意味着,如果你需要不同的回调行为,应该初始化一个单独的 *gorm.DB 实例。

注册回调

你可以为特定操作注册回调。例如,要添加一个自定义的图片裁剪功能:

func cropImage(db *gorm.DB) {
  if db.Statement.Schema != nil {
    
    for _, field := range db.Statement.Schema.Fields {
      switch db.Statement.ReflectValue.Kind() {
      case reflect.Slice, reflect.Array:
        for i := 0; i < db.Statement.ReflectValue.Len(); i++ {
          
          if fieldValue, isZero := field.ValueOf(db.Statement.Context, db.Statement.ReflectValue.Index(i)); !isZero {
            if crop, ok := fieldValue.(CropInterface); ok {
              crop.Crop()
            }
          }
        }
      case reflect.Struct:
        
        if fieldValue, isZero := field.ValueOf(db.Statement.Context, db.Statement.ReflectValue); !isZero {
          if crop, ok := fieldValue.(CropInterface); ok {
            crop.Crop()
          }
        }

        
        err := field.Set(db.Statement.Context, db.Statement.ReflectValue, "newValue")
      }
    }

    
    db.Statement.Schema.Fields

    
    db.Statement.Schema.PrimaryFields

    
    db.Statement.Schema.PrioritizedPrimaryField

    
    db.Statement.Schema.Relationships

    
    field := db.Statement.Schema.LookUpField("Name")

    
  }
}


db.Callback().Create().Register("crop_image", cropImage)

删除回调

如果不再需要某个回调,可以将其移除:


db.Callback().Create().Remove("gorm:create")

替换回调

同名的回调可以用新函数替换:


db.Callback().Create().Replace("gorm:create", newCreateFunction)

回调排序

可以按特定顺序注册回调,以确保它们在操作生命周期中的正确时间执行。


db.Callback().Create().Before("gorm:create").Register("update_created_at", updateCreated)


db.Callback().Create().After("gorm:create").Register("update_created_at", updateCreated)


db.Callback().Query().After("gorm:query").Register("my_plugin:after_query", afterQuery)


db.Callback().Delete().After("gorm:delete").Register("my_plugin:after_delete", afterDelete)


db.Callback().Update().Before("gorm:update").Register("my_plugin:before_update", beforeUpdate)


db.Callback().Create().Before("gorm:create").After("gorm:before_create").Register("my_plugin:before_create", beforeCreate)


db.Callback().Create().Before("*").Register("update_created_at", updateCreated)


db.Callback().Create().After("*").Register("update_created_at", updateCreated)

预定义回调

GORM 附带一组预定义的回调来驱动其标准功能。在创建自定义插件或附加回调函数之前,建议先查看这些已定义的回调

插件

GORM 的插件系统允许轻松扩展和定制其核心功能,在保持模块化架构的同时增强应用程序的能力。

插件接口

要为 GORM 创建插件,你需要定义一个实现 Plugin 接口的结构体:

type Plugin interface {
  Name() string
  Initialize(*gorm.DB) error
}
  • Name 方法:返回插件的唯一字符串标识符。
  • Initialize 方法:包含设置插件的逻辑。当插件首次注册到 GORM 时,会调用此方法。

注册插件

一旦你的插件符合 Plugin 接口,你就可以将其注册到一个 GORM 实例:


db.Use(MyCustomPlugin{})

访问已注册的插件

插件注册后,它会被存储在 GORM 的配置中。你可以通过 Plugins 映射访问已注册的插件:


plugin := db.Config.Plugins[pluginName]

实践示例

GORM 插件的一个例子是 Prometheus 插件,它将 Prometheus 监控与 GORM 集成:


db.Use(prometheus.New(prometheus.Config{
  
}))

Prometheus 插件文档 提供了关于其具体实现和使用的详细信息。

GitHub tag (latest SemVer)

评论

登录后参与评论

正在加载评论…