GORM 软删除查询过滤
GORM 软删除机制会在查询时自动过滤已删除记录,本文介绍其工作原理与例外场景。
软删除定义
软删除不物理删除数据,而是将 DeletedAt 字段设为当前时间。查询时 GORM 自动追加 WHERE deleted_at IS NULL 条件。
Go
type User struct {
ID uint
Name string
DeletedAt gorm.DeletedAt `gorm:"index"`
}
自动查询过滤
执行 Find、First、Where 等查询时,GORM 自动追加过滤条件:
Go
// 生成 SQL: SELECT * FROM users WHERE name = 'test' AND deleted_at IS NULL
db.Where("name = ?", "test").Find(&users)
// 生成 SQL: SELECT * FROM users WHERE id = 1 AND deleted_at IS NULL
db.First(&user, 1)
Unscoped 查询已删除记录
使用 Unscoped() 可跳过软删除过滤,查询包含已删除的记录:
Go
// 生成 SQL: SELECT * FROM users WHERE deleted_at IS NOT NULL
db.Unscoped().Where("deleted_at IS NOT NULL").Find(&deletedUsers)
// 生成 SQL: SELECT * FROM users WHERE id = 1 (无 deleted_at 过滤)
db.Unscoped().First(&user, 1)
例外场景
以下场景 GORM 不会自动追加软删除过滤:
| 场景 | 说明 |
|---|---|
使用 Unscoped() | 明确跳过软删除过滤 |
| 原生 SQL 查询 | db.Raw() 不自动追加条件 |
| 关联查询 Preload | 关联表无软删除字段时不过滤 |
| Count 查询 | 需显式加条件或 Unscoped |
原生 SQL 需手动追加
AND deleted_at IS NULL条件。
要点总结
- 软删除将
DeletedAt设为删除时间而非物理删除 - 常规查询自动追加
deleted_at IS NULL过滤条件 - 使用
Unscoped()跳过过滤查询已删除记录 - 原生 SQL 不自动追加过滤,需手动处理
文章存放路径:D:\git2\jwdev\articles\GORM\进阶\软删除机制\软删除查询过滤.md
📝 发现内容有误?点击此处直接编辑