GORM DeletedAt 字段使用
GORM 软删除机制通过 gorm.DeletedAt 字段实现逻辑删除,避免物理删除导致数据丢失。
软删除原理
工作方式
- 调用
Delete时自动将deleted_at字段设为当前时间 - 查询时自动添加
WHERE deleted_at IS NULL条件 - 数据仍保留数据库中,可通过特殊查询恢复
基本使用
模型定义
Go
type User struct {
gorm.Model // 内置包含 DeletedAt 字段
Name string
Email string
}
// 或手动定义
type Product struct {
ID uint
Name string
DeletedAt gorm.DeletedAt `gorm:"index"`
}
执行软删除
Go
// 软删除单条记录
db.Delete(&user)
// 软删除多条记录
db.Delete(&users, []int{1, 2, 3})
// 根据条件软删除
db.Where("status = ?", "inactive").Delete(&User{})
生成的 SQL
SQL
UPDATE users SET deleted_at='2026-05-21 10:30:00' WHERE id = 1 AND deleted_at IS NULL
查询与恢复
查询已删除记录
Go
// 包含已删除记录
db.Unscoped().Find(&users)
// 仅查询已删除记录
db.Unscoped().Where("deleted_at IS NOT NULL").Find(&deletedUsers)
恢复数据
Go
// 恢复单条记录
db.Unscoped().Where("id = ?", 1).Update("deleted_at", nil)
// 批量恢复
db.Unscoped().Where("id IN ?", []int{1, 2, 3}).Update("deleted_at", nil)
软删除 vs 物理删除
| 操作 | 方法 | SQL |
|---|---|---|
| 软删除 | db.Delete() | UPDATE SET deleted_at = NOW() |
| 物理删除 | db.Unscoped().Delete() | DELETE FROM table |
| 软删除查询 | db.Where().Delete() | UPDATE SET deleted_at = NOW() |
| 物理删除查询 | db.Unscoped().Where().Delete() | DELETE FROM table |
注意事项
gorm.Model已内置DeletedAt字段,嵌入即可启用软删除。
软删除的字段类型必须为
gorm.DeletedAt,而非普通time.Time。
唯一索引需考虑
deleted_at,避免软删除后冲突。
物理删除需显式调用
Unscoped(),防止误操作。
要点总结
- 软删除通过
gorm.DeletedAt字段实现,调用Delete自动设置删除时间 - 查询默认过滤已删除记录,使用
Unscoped()可查询已删除数据 - 恢复数据需将
deleted_at字段置为nil - 软删除保留数据便于审计与恢复,但增加存储空间与查询复杂度
- 物理删除需显式调用
Unscoped(),避免误删数据
存放路径:D:\git2\jwdev\articles\GORM\进阶\软删除机制\DeletedAt 字段使用.md
📝 发现内容有误?点击此处直接编辑