如何轻松运用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语言框架
推荐阅读
-
如何在Unity中轻松运用OnTriggerEnter功能
-
在Vim编辑器或其插件中,如何轻松地完成"用选中的一个词替换单词内的某个特定词"操作?
-
如何轻松创建React中的倒计时功能:实现解耦与通用方法指南
-
如何轻松掌握与理解网页开发中的namespace声明与运用
-
如何轻松实现H5网页中的扫码功能调起指南
-
在MATLAB中轻松实现1stopt插件的拟合功能指南
-
详解pytest中的Hook函数(钩子机制)" || "轻松掌握pytest:如何利用pytest_terminal_summary进行测试结果统计
-
如何轻松运用Gorm插件中的Hook功能
-
南邮OJ Web任务大揭秘:层层挑战剖析 1. 挑战一:迷宫般的目录探索 题目作者似乎穷举了所有可能的目录组合,最终在404.php中的