Gorm:钩子Hook
Hook 是在创建、查询、更新、删除等操作之前、之后调用的函数。
支持以下的Hook方法
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:
BeforeSave BeforeCreate
AfterCreate AfterSave
|
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:
BeforeSave BeforeUpdate
AfterUpdate AfterSave
|
删除对象
可用Hook:
查询对象
修改当前操作
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
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 } } }
|