欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

如何轻松运用Gorm插件中的Hook功能

最编程 2024-02-11 21:23:41
...

1. hook 介绍

hook 钩子函数,是指当满足一定的触发条件时会自动触发的函数,我们能借助 Gorm 框架对数据库进行 CRUD 操作,对于这些操作,我们能绑定特定的 hook 函数,进行方法的加强。

2. hook 的使用

需要注意的是,Gorm 中的 hook 是绑定在 model 对象而不是 gorm.DB 上的。

package main

import (
   "fmt"
   "gorm.io/driver/sqlite"
   "gorm.io/gorm"
)

type Product struct {
   gorm.Model
   Code  string
   Price uint
}

func (p *Product) BeforeCreate(tx *gorm.DB) (err error) {
   fmt.Print("BeforeCreate......")
   return
}

func main() {
   db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
   if err != nil {
      panic("failed to connect database")
   }

   // Create
   db.Create(&Product{Code: "D41", Price: 100})

}

以上面的代码为例,我们能发现,在 Product 这个model 的 Create 操作之前,会触发他的 BeforeCreate 的 hook 钩子函数。

3. hock 接口

针对不同的操作,Gorm为我们提供了不同的hook方法:

//gorm/callbacks/interface.go
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接口,我们可以将其使用总结为如下部分:

Save BeforeCreate/AfterCreate/BeforeSave/AfterSave 一次
Create BeforeCreate/AfterCreate/BeforeSave/AfterSave 数组形式插入触发多次,create from map方式不会触发
Update BeforeUpdate/AfterUpdate/BeforeSave/AfterSave 一次
Delete BeforeDelete/AfterDelete 一次
Find/First/Last/Take AfterFind 查出几条数据则触发几次

另外需要注意的是,如果在不同的hook中发生了error,会有不同的效果:

hook return error后果
BeforeUpdate/BeforeSave/BeforeCreate 停止之后的执行
AfterUpdate/AfterSave/AfterCreate/AfterDelete 使得之前的数据库写入操作回滚
AfterFind 继续执行

总结起来,如果是幂等操作(不会对数据库造成影响的操作,例如查找操作),并不会触发回滚,如果是非幂等操作(增删改等会影响数据库数据的操作),其 hook 的报错会引起事务性的回滚。

本文正在参加技术专题18期-聊聊Go语言框架

推荐阅读