扫码一下
查看教程更方便
hook 是在创建、查询、更新、删除等操作之前、之后调用的函数。
如果我们已经为模型定义了指定的方法,它会在创建、更新、查询、删除时自动被调用。如果任何回调返回错误,gorm 将停止后续的操作并回滚事务。
钩子方法的函数签名应该是 func(*gorm.db) error
创建时可用的 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
}