GORM 删除记录
GORM 的 Delete 方法支持软删除和硬删除,默认根据模型是否包含 DeletedAt 字段自动判断。
定义
Delete 方法删除单条或多条记录。含 gorm.DeletedAt 字段时执行软删除(更新删除时间),否则执行硬删除(物理删除)。
语法
Go
func (db *DB) Delete(value interface{}, conds ...interface{}) (tx *DB)
func (db *DB) Unscoped() (tx *DB)
示例
软删除
Go
type User struct {
gorm.Model // 包含 DeletedAt 字段
Name string
}
// 软删除(更新 deleted_at 为当前时间)
db.Delete(&user)
// UPDATE users SET deleted_at=NOW() WHERE id=1
硬删除
Go
type Product struct {
ID uint `gorm:"primaryKey"`
Name string
// 无 DeletedAt 字段
}
// 硬删除(直接从数据库移除)
db.Delete(&product)
// DELETE FROM products WHERE id=1
强制硬删除(跳过软删除)
Go
// 即使有 DeletedAt 字段,也执行物理删除
db.Unscoped().Delete(&user)
// DELETE FROM users WHERE id=1
批量删除
Go
db.Where("age > ?", 30).Delete(&User{})
// DELETE FROM users WHERE age > 30
// 传入切片批量删除
db.Delete(&[]User{{ID: 1}, {ID: 2}, {ID: 3}})
按主键删除
Go
db.Delete(&User{}, 10)
// DELETE FROM users WHERE id = 10
软删除与硬删除对比
| 类型 | 触发条件 | SQL 类型 | 数据可恢复 |
|---|---|---|---|
| 软删除 | 模型含 DeletedAt 字段 | UPDATE | 是 |
| 硬删除 | 模型无 DeletedAt 字段 | DELETE | 否 |
| 强制硬删除 | 使用 Unscoped() | DELETE | 否 |
注意事项
- 软删除后查询默认过滤已删除记录,需用
Unscoped()查询已删除数据- 唯一索引冲突场景下,软删除可能导致重复值,需添加部分唯一索引
Delete返回RowsAffected为实际删除/更新行数- 批量删除无钩子回调(
BeforeDelete、AfterDelete不触发)- 使用
gorm.DeletedAt类型而非time.Time以启用软删除
要点总结
- 含
DeletedAt字段时Delete执行软删除(UPDATE) - 无
DeletedAt字段或使用Unscoped()执行硬删除(DELETE) - 支持按主键、条件、切片批量删除
- 软删除数据可用
Unscoped()查询或恢复 - 批量删除不触发钩子函数
📝 发现内容有误?点击此处直接编辑