教程

钩子

qianmoQqianmoQ· 更新于 2026-09-23· 阅读 5 分钟· 0 次阅读

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

对象生命周期

钩子(Hooks)是在创建/查询/更新/删除之前或之后调用的函数。

如果你为模型定义了指定的方法,它会在创建、更新、查询、删除时被自动调用。如果任何回调返回了错误,GORM 将停止后续操作并回滚当前事务。

钩子方法的类型应为 func(*gorm.DB) error

钩子

创建对象

创建时可用的钩子:


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
}

注意 GORM 中的保存/删除操作默认在事务中运行,因此在事务提交之前,所做的更改是不可见的。如果你在钩子中返回了任何错误,更改将被回滚。

func (u *User) AfterCreate(tx *gorm.DB) (err error) {
  if !u.IsValid() {
    return errors.New("rollback invalid user")
  }
  return nil
}

更新对象

更新时可用的钩子:


BeforeSave
BeforeUpdate



AfterUpdate
AfterSave

代码示例:

func (u *User) BeforeUpdate(tx *gorm.DB) (err error) {
  if u.readonly() {
    err = errors.New("read only user")
  }
  return
}


func (u *User) AfterUpdate(tx *gorm.DB) (err error) {
  if u.Confirmed {
    tx.Model(&Address{}).Where("user_id = ?", u.ID).Update("verfied", true)
  }
  return
}

删除对象

删除时可用的钩子:


BeforeDelete

AfterDelete

代码示例:


func (u *User) AfterDelete(tx *gorm.DB) (err error) {
  if u.Confirmed {
    tx.Model(&Address{}).Where("user_id = ?", u.ID).Update("invalid", false)
  }
  return
}

查询对象

查询时可用的钩子:



AfterFind

代码示例:

func (u *User) AfterFind(tx *gorm.DB) (err error) {
  if u.MemberShip == "" {
    u.MemberShip = "user"
  }
  return
}

修改当前操作

func (u *User) BeforeCreate(tx *gorm.DB) error {
  
  tx.Statement.Select("Name", "Age")
  tx.Statement.AddClause(clause.OnConflict{DoNothing: true})

  
  
  var role Role
  err := tx.First(&role, "name = ?", user.Role).Error
  
  
  return err
}

GitHub tag (latest SemVer)

评论

登录后参与评论

正在加载评论…