删除
删除
删除记录删除记录
删除记录时,被删除的值需要包含主键,否则将触发批量删除,例如:
泛型 API泛型 API
ctx := context.Background()
err := gorm.G[Email](db).Where("id = ?", 10).Delete(ctx)
err := gorm.G[Email](db).Where("id = ? AND name = ?", 10, "jinzhu").Delete(ctx)
传统 API传统 API
db.Delete(&email)
db.Where("name = ?", "jinzhu").Delete(&email)
使用主键删除使用主键删除
GORM 允许使用内联条件通过主键删除对象,支持数字类型,详情请参阅查询内联条件
db.Delete(&User{}, 10)
db.Delete(&User{}, "10")
db.Delete(&users, []int{1,2,3})
删除钩子删除钩子
GORM 支持 BeforeDelete、AfterDelete 钩子,这些方法会在删除记录时被调用,详情请参阅钩子
func (u *User) BeforeDelete(tx *gorm.DB) (err error) {
if u.Role == "admin" {
return errors.New("admin user not allowed to delete")
}
return
}批量删除批量删除
指定的值不包含主键时,GORM 将执行批量删除,删除所有匹配的记录
泛型 API泛型 API
ctx := context.Background()
err := gorm.G[Email](db).Where("email LIKE ?", "%jinzhu%").Delete(ctx)
传统 API传统 API
db.Where("email LIKE ?", "%jinzhu%").Delete(&Email{})
db.Delete(&Email{}, "email LIKE ?", "%jinzhu%")
要高效删除大量记录,请将包含主键的切片传递给 Delete 方法。
var users = []User{{ID: 1}, {ID: 2}, {ID: 3}}
db.Delete(&users)
db.Delete(&users, "name LIKE ?", "%jinzhu%")
阻止全局删除阻止全局删除
如果执行不带任何条件的批量删除,GORM 不会执行该操作,并会返回 ErrMissingWhereClause 错误
您必须使用某些条件,或使用原生 SQL,或启用 AllowGlobalUpdate 模式,例如:
泛型 API泛型 API
ctx := context.Background()
err := gorm.G[User](db).Delete(ctx)
err := gorm.G[User](db).Where("1 = 1").Delete(ctx)
传统 API传统 API
db.Delete(&User{}).Error
db.Delete(&[]User{{Name: "jinzhu1"}, {Name: "jinzhu2"}}).Error
db.Where("1 = 1").Delete(&User{})
db.Exec("DELETE FROM users")
db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&User{})
从删除的行返回数据从删除的行返回数据
返回被删除的数据,仅适用于支持 Returning 的数据库,例如:
var users []User
DB.Clauses(clause.Returning{}).Where("role = ?", "admin").Delete(&users)
DB.Clauses(clause.Returning{Columns: []clause.Column{{Name: "name"}, {Name: "salary"}}}).Where("role = ?", "admin").Delete(&users)
软删除软删除
如果您的模型包含 gorm.DeletedAt 字段(gorm.Model 中已包含该字段),它将自动获得软删除能力!
调用 Delete 时,记录不会从数据库中移除,而是 GORM 将 DeletedAt 的值设置为当前时间,之后通过普通查询方法无法再找到该数据。
db.Delete(&user)
db.Where("age = ?", 20).Delete(&User{})
db.Where("age = 20").Find(&user)
如果您不想使用 gorm.Model,可以这样启用软删除功能:
type User struct {
ID int
Deleted gorm.DeletedAt
Name string
}查询软删除的记录查询软删除的记录
可以使用 Unscoped 查询软删除的记录
db.Unscoped().Where("age = 20").Find(&users)
永久删除永久删除
可以使用 Unscoped 永久删除匹配的记录
db.Unscoped().Delete(&order)
删除标志删除标志
默认情况下,gorm.Model 使用 *time.Time 作为 DeletedAt 字段的值,并通过插件 gorm.io/plugin/soft_delete 提供其他数据格式支持
提示 为 DeletedAt 字段创建唯一复合索引时,必须借助插件
gorm.io/plugin/soft_delete使用其他数据格式,如 unix 秒/标志位,例如: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"
}
Unix 秒Unix 秒
使用 unix 秒作为删除标志
import "gorm.io/plugin/soft_delete"
type User struct {
ID uint
Name string
DeletedAt soft_delete.DeletedAt
}
SELECT * FROM users WHERE deleted_at = 0;
UPDATE users SET deleted_at = WHERE ID = 1;也可以指定使用 milli(毫秒)或 nano(纳秒)作为值,例如:
type User struct {
ID uint
Name string
DeletedAt soft_delete.DeletedAt `gorm:"softDelete:milli"`
}
SELECT * FROM users WHERE deleted_at = 0;
UPDATE users SET deleted_at = WHERE ID = 1;使用 1 / 0 作为删除标志使用 1 / 0 作为删除标志
import "gorm.io/plugin/soft_delete"
type User struct {
ID uint
Name string
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag"`
}
SELECT * FROM users WHERE is_del = 0;
UPDATE users SET is_del = 1 WHERE ID = 1;混合模式混合模式
混合模式可以使用 0、1 或 unix 秒来标记数据是否已删除,同时保存删除时间。
type User struct {
ID uint
Name string
DeletedAt time.Time
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"`
}
SELECT * FROM users WHERE is_del = 0;
UPDATE users SET is_del = 1, deleted_at = WHERE ID = 1;评论
登录后参与评论
KnowForge