删除一条记录
删除一条记录时,删除对象需要指定主键,否则会触发 批量 Delete,例如:
// Email 的 ID 是 `10` |
根据主键删除
GORM 允许通过主键(可以是复合主键)和内联条件来删除对象,它可以使用数字(如以下例子。也可以使用字符串——译者注)。查看 查询-内联条件(Query Inline Conditions) 了解详情。
db.Delete(&User{}, 10) |
Delete Hook
对于删除操作,GORM 支持 BeforeDelete
、AfterDelete
Hook,在删除记录时会调用这些方法,查看 Hook 获取详情
func (u *User) BeforeDelete(tx *gorm.DB) (err error) { |
批量删除
如果指定的值不包括主属性,那么 GORM 会执行批量删除,它将删除所有匹配的记录
db.Where("email LIKE ?", "%jinzhu%").Delete(&Email{}) |
阻止全局删除
如果在没有任何条件的情况下执行批量删除,GORM 不会执行该操作,并返回 ErrMissingWhereClause
错误
对此,你必须加一些条件,或者使用原生 SQL,或者启用 AllowGlobalUpdate
模式,例如:
db.Delete(&User{}).Error // gorm.ErrMissingWhereClause |
返回删除行的数据
返回被删除的数据,仅适用于支持 Returning 的数据库,例如:
// 返回所有列 |
软删除
如果您的模型包含了一个 gorm.deletedat
字段(gorm.Model
已经包含了该字段),它将自动获得软删除的能力!
拥有软删除能力的模型调用 Delete
时,记录不会从数据库中被真正删除。但 GORM 会将 DeletedAt
置为当前时间, 并且你不能再通过普通的查询方法找到该记录。
// user 的 ID 是 `111` |
如果您不想引入 gorm.Model
,您也可以这样启用软删除特性:
type User struct { |
查找被软删除的记录
您可以使用 Unscoped
找到被软删除的记录
db.Unscoped().Where("age = 20").Find(&users) |
永久删除
您也可以使用 Unscoped
永久删除匹配的记录
db.Unscoped().Delete(&order) |
Delete Flag
将 unix 时间戳作为 delete flag
import "gorm.io/plugin/soft_delete" |
INFO 在配合 unique 字段使用软删除时,您需要使用这个基于 unix 时间戳的
DeletedAt
字段创建一个复合索引,例如:
import "gorm.io/plugin/soft_delete"
type User struct {
ID uint
Name string `gorm:"uniqueIndex:udx_name"`
DeletedAt soft_delete.DeletedAt `gorm:"uniqueIndex:udx_name"`
}
使用 1
/ 0
作为 delete flag
import "gorm.io/plugin/soft_delete" |