下面的几种方法,不会触发钩子事件.
type User struct{
Name string `gorm:"column:name"`
}
func (u *User) BeforeDelete(tx *gorm.DB) (err error) {
fmt.Printf("正在删除用户%v\n",u.Name)
return
}
func main(){
//下面的方法均不会触发钩子
//1.
db.Delete(&User{}, 1)
//2.
db.Delete(&User{}, "id in ?", ids)
//3.
var ids = []uint{1,2,3}
db.Where("id in ?",ids).Delete(&User{})
}
原因说明
下面的例子,可以正确触发BeforeDelete
钩子,只要给user随便填充点数据即可
var user= User{Name: "张三"}
err = global.GVA_DB.Where("id = 1").Delete(&user).Error
因为,钩子BeforeDelete
执行前,gorm会判断如果user
变量中没有任何数据,如果没有则不会去执行BeforeDelete
方法。
这里,很多人会犯一个理解性的错误,在面向对象的角度来看,会以为钩子里面操作的是Where("id = 1")
中查到的数据。
其实这里仅仅只是执行了sql删除语句DELETE FROM user WHERE id =1;
,并没有执行查询方法。目的也很简单,减少数据库的连接。
如果要触发钩子事件,可以参考下面的方法。
先用First
或Find
获取到数据,再用Delete删除。
//单条删除
var user User
db.Where("id =1").Find(&user).Delete(&user)
//多条删除
var users []user
var ids = []uint{1,2,3}
db.Where("id in ?", ids).Find(&users).Delete(&users)