Callbacks

GORM 自身也是基于 Callbacks 的,包括 CreateQueryUpdateDeleteRowRaw。此外,您也完全可以根据自己的意愿自定义 GORM

回调会注册到全局 *gorm.DB,而不是会话级别。如果您想要 *gorm.DB 具有不同的回调,您需要初始化另一个 *gorm.DB

注册回调

注册回调至 callbacks

  1. func cropImage(db *gorm.DB) {
  2. if db.Statement.Schema != nil {
  3. // 伪代码:裁剪图片字段并将其上传至 CDN
  4. for _, field := range db.Statement.Schema.Fields {
  5. switch db.Statement.ReflectValue.Kind() {
  6. case reflect.Slice, reflect.Array:
  7. for i := 0; i < db.Statement.ReflectValue.Len(); i++ {
  8. // 从字段获取 value
  9. if fieldValue, isZero := field.ValueOf(db.Statement.ReflectValue.Index(i)); !isZero {
  10. if crop, ok := fieldValue.(CropInterface); ok {
  11. crop.Crop()
  12. }
  13. }
  14. }
  15. case reflect.Struct:
  16. // 从字段获取 value
  17. if fieldValue, isZero := field.ValueOf(db.Statement.ReflectValue); isZero {
  18. if crop, ok := fieldValue.(CropInterface); ok {
  19. crop.Crop()
  20. }
  21. }
  22. // 设置字段的 value
  23. err := field.Set(db.Statement.ReflectValue, "newValue")
  24. }
  25. }
  26. // 当前 model 的所有字段
  27. db.Statement.Schema.Fields
  28. // 当前 model 的所有主键字段
  29. db.Statement.Schema.PrimaryFields
  30. // 优先的主键字段:DB 列名为 `id` 或定义的第一个主键
  31. db.Statement.Schema.PrioritizedPrimaryField
  32. // 当前 model 的所有关系
  33. db.Statement.Schema.Relationships
  34. field := db.Statement.Schema.LookUpField("Name")
  35. // 处理...
  36. }
  37. }
  38. db.Callback().Create().Register("crop_image", cropImage)
  39. // 为 Crete 流程注册一个回调

删除回调

从 callbacks 中删除回调

  1. db.Callback().Create().Remove("gorm:create")
  2. // 从 Create 的 callbacks 中删除 `gorm:create`

替换回调

用一个新的回调替换已有的同名回调

  1. db.Callback().Create().Replace("gorm:create", newCreateFunction)
  2. // 用新函数 `newCreateFunction` 替换 Create 流程目前的 `gorm:create`

注册带顺序的回调

注册带顺序的回调

  1. db.Callback().Create().Before("gorm:create").Register("update_created_at", updateCreated)
  2. db.Callback().Create().After("gorm:create").Register("update_created_at", updateCreated)
  3. db.Callback().Query().After("gorm:query").Register("my_plugin:after_query", afterQuery)
  4. db.Callback().Delete().After("gorm:delete").Register("my_plugin:after_delete", afterDelete)
  5. db.Callback().Update().Before("gorm:update").Register("my_plugin:before_update", beforeUpdate)
  6. db.Callback().Create().Before("gorm:create").After("gorm:before_create").Register("my_plugin:before_create", beforeCreate)

预定义回调

GORM 已经定义了 一些回调 来支持当前的 GORM 功能,在启动您的插件之前可以先看看这些回调

插件

GORM 提供了 Use 方法来注册插件,插件需要实现 Plugin 接口

  1. type Plugin interface {
  2. Name() string
  3. Initialize(*gorm.DB) error
  4. }

当插件首次注册到 GORM 时将调用 Initialize 方法,且 GORM 会保存已注册的插件,你可以这样访问访问:

  1. db.Config.Plugins[pluginName]

查看 Prometheus 的例子