GORM 创建钩子实现
本文介绍 GORM 中创建操作的钩子函数实现方法。
钩子方法
BeforeCreate
在记录插入数据库之前执行,常用于数据预处理。
Go
type User struct {
ID uint
Name string
Email string
Password string
UUID string
CreatedAt time.Time
}
// 插入前自动生成 UUID 和加密密码
func (u *User) BeforeCreate(tx *gorm.DB) error {
u.UUID = uuid.New().String()
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
if err != nil {
return err
}
u.Password = string(hashedPassword)
return nil
}
BeforeCreate 返回 error 时,创建操作会被中止并回滚事务。
AfterCreate
在记录插入数据库之后执行,常用于触发后续操作。
Go
type Order struct {
ID uint
UserID uint
Amount float64
Status string
}
// 插入后发送通知或写入日志
func (o *Order) AfterCreate(tx *gorm.DB) error {
// 发送订单通知
err := sendNotification(o.UserID, "订单创建成功")
if err != nil {
// 注意:此处错误不会回滚主事务
log.Printf("send notification failed: %v", err)
}
return nil
}
AfterCreate 返回的 error 不会回滚主事务,仅记录日志。
钩子方法签名
Go
// 创建前钩子
func (model *ModelName) BeforeCreate(tx *gorm.DB) error
// 创建后钩子
func (model *ModelName) AfterCreate(tx *gorm.DB) error
在钩子中使用事务
Go
func (u *User) BeforeCreate(tx *gorm.DB) error {
// 在钩子事务中执行额外操作
var count int64
tx.Raw("SELECT COUNT(*) FROM users WHERE email = ?", u.Email).Scan(&count)
if count > 0 {
return errors.New("邮箱已存在")
}
return nil
}
跳过钩子
Go
// 跳过所有钩子
db.Session(&gorm.Session{SkipHooks: true}).Create(&user)
注意事项
- BeforeCreate 返回非 nil error 时,整个创建操作会被回滚。
- AfterCreate 返回的 error 不影响已提交的数据库写入。
- 钩子方法在批量 Create 时会对每条记录执行。
- 钩子中使用
tx参数可在同一事务内执行额外查询。- 使用
SkipHooks: true可在特定场景跳过所有钩子。
要点总结
- BeforeCreate在插入前执行,返回 error 可中止操作并回滚事务。
- AfterCreate在插入后执行,适合触发异步或后续操作。
- 钩子方法接收
*gorm.DB参数,可在同一事务内执行额外查询。 - 钩子可用于数据预处理(如加密、生成 UUID)和业务逻辑触发。
SkipHooks选项可在需要时跳过所有钩子执行。
存放路径:D:\git2\jwdev\articles\GORM\进阶\钩子函数与回调机制\创建钩子实现.md
📝 发现内容有误?点击此处直接编辑