Advanced Topics

Write Plugins

qianmoQqianmoQ· 更新于 2026-09-15· 阅读 12 分钟· 0 次阅读

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

Callbacks

GORM leverages Callbacks to power its core functionalities. These callbacks provide hooks for various database operations like Create, Query, Update, Delete, Row, and Raw, allowing for extensive customization of GORM’s behavior.

Callbacks are registered at the global *gorm.DB level, not on a session basis. This means if you need different callback behaviors, you should initialize a separate *gorm.DB instance.

Registering a Callback

You can register a callback for specific operations. For example, to add a custom image cropping functionality:

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)

Deleting a Callback

If a callback is no longer needed, it can be removed:


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

Replacing a Callback

Callbacks with the same name can be replaced with a new function:


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

Ordering Callbacks

Callbacks can be registered with specific orders to ensure they execute at the right time in the operation lifecycle.


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)

Predefined Callbacks

GORM comes with a set of predefined callbacks that drive its standard features. It’s recommended to review these defined callbacks before creating custom plugins or additional callback functions.

Plugins

GORM’s plugin system allows for easy extensibility and customization of its core functionalities, enhancing your application’s capabilities while maintaining a modular architecture.

The Plugin Interface

To create a plugin for GORM, you need to define a struct that implements the Plugin interface:

type Plugin interface {
  Name() string
  Initialize(*gorm.DB) error
}
  • Name Method: Returns a unique string identifier for the plugin.
  • Initialize Method: Contains the logic to set up the plugin. This method is called when the plugin is registered with GORM for the first time.

Registering a Plugin

Once your plugin conforms to the Plugin interface, you can register it with a GORM instance:


db.Use(MyCustomPlugin{})

Accessing Registered Plugins

After a plugin is registered, it is stored in GORM’s configuration. You can access registered plugins via the Plugins map:


plugin := db.Config.Plugins[pluginName]

Practical Example

An example of a GORM plugin is the Prometheus plugin, which integrates Prometheus monitoring with GORM:


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

Prometheus plugin documentation provides detailed information on its implementation and usage.

GitHub tag (latest SemVer)

评论

登录后参与评论

正在加载评论…