Gorm:钩子Hook
Hook 是在创建、查询、更新、删除等操作之前、之后调用的函数。
支持以下的Hook方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
   | type BeforeCreateInterface interface {     BeforeCreate(*gorm.DB) error }
  type AfterCreateInterface interface {     AfterCreate(*gorm.DB) error }
  type BeforeUpdateInterface interface {     BeforeUpdate(*gorm.DB) error }
  type AfterUpdateInterface interface {     AfterUpdate(*gorm.DB) error }
  type BeforeSaveInterface interface {     BeforeSave(*gorm.DB) error }
  type AfterSaveInterface interface {     AfterSave(*gorm.DB) error }
  type BeforeDeleteInterface interface {     BeforeDelete(*gorm.DB) error }
  type AfterDeleteInterface interface {     AfterDelete(*gorm.DB) error }
  type AfterFindInterface interface {     AfterFind(*gorm.DB) error }
  | 
 
创建对象
注意 在 GORM 中保存、删除操作会默认运行在事务上, 因此在事务完成之前该事务中所作的更改是不可见的,如果您的钩子返回了任何错误,则修改将被回滚		
可用Hook:
1 2 3 4 5 6 7 8 9
   |  BeforeSave BeforeCreate
 
 
  AfterCreate AfterSave
 
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | func (u *User) BeforeCreate(tx *gorm.DB) (err error) {   u.UUID = uuid.New()
    if !u.IsValid() {     err = errors.New("can't save invalid data")   }   return }
  func (u *User) AfterCreate(tx *gorm.DB) (err error) {   if u.ID == 1 {     tx.Model(u).Update("role", "admin")   }   return }
  | 
 
更新对象
可用Hook:
1 2 3 4 5 6 7 8 9
   |  BeforeSave BeforeUpdate
 
 
  AfterUpdate AfterSave
 
 
  | 
 
删除对象
可用Hook:
1 2 3 4 5
   |  BeforeDelete
  AfterDelete
 
 
  | 
 
查询对象
修改当前操作
1 2 3 4 5 6 7 8 9 10 11 12
   | func (u *User) BeforeCreate(tx *gorm.DB) error {      tx.Statement.Select("Name", "Age")   tx.Statement.AddClause(clause.OnConflict{DoNothing: true})
          err := tx.First(&role, "name = ?", user.Role).Error         return err }
  | 
 
自定义Hook
⚠️这里的afterCreate中db 当我们传入其他gorm操作执行SQL的时候,已经是HestiaInstanceModel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
   | func RegisterHook(db *gorm.DB) {               if err := db.Callback().Create().After("gorm:create").Register("hestia_instance_after_create", afterCreate); err != nil {        slog.Error("register hestia_instance_after_create failed", slog.Any("err", err))     } }
  func afterCreate(db *gorm.DB) {     if m, ok := db.Statement.Model.(*basismodel.HestiaInstanceModel); ok {        ctx := db.Statement.Context        username := getUsername(ctx)        db.Model(m).UpdateColumn("created_by", username)        db.Model(m).UpdateColumn("request_id", ctx.Value("request-id"))        repo := repository.NewDBInstanceRepository(middleware.CommonDB)        dbService := service.NewDBInstanceService(repo)        dbInstanceInfo, err := fromDBInStanceModel(m)        if err != nil {           slog.Error("afterCreate fromModel error", slog.Any("err", err))           return        }        if err := dbService.CreateDBInstance(context.Background(), dbInstanceInfo); err != nil {           slog.Error("afterCreate create db_instance error", slog.Any("err", err))           return        }     } }
  |