教程 > gorm 教程 > 阅读:151

gorm 钩子 hook——迹忆客-ag捕鱼王app官网

对象生命周期

hook 是在创建、查询、更新、删除等操作之前、之后调用的函数。

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

钩子方法的函数签名应该是 func(*gorm.db) error

hook

创建对象

创建时可用的 hook

// 开始事务
beforesave
beforecreate
// 关联前的 save
// 插入记录至 db
// 关联后的 save
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
}

更新对象

更新时可用的 hook

// 开始事务
beforesave
beforeupdate
// 关联前的 save
// 更新 db
// 关联后的 save
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
}

删除对象

删除时可用的 hook

// 开始事务
beforedelete
// 删除 db 中的数据
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
}

查询对象

查询时可用的 hook

// 从 db 中加载数据
// preloading (eager loading)
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 修改当前操作,例如:
  tx.statement.select("name", "age")
  tx.statement.addclause(clause.onconflict{donothing: true})
  // tx 是带有 `newdb` 选项的新会话模式 
  // 基于 tx 的操作会在同一个事务中,但不会带上任何当前的条件
  err := tx.first(&role, "name = ?", user.role).error
  // select * from roles where name = "admin"
  // ...
  return err
}

查看笔记

扫码一下
查看教程更方便
网站地图