如何在 SpringBoot 项目中优雅实现软删除功能?附全流程实战
软删除(Soft Delete)是指在数据库中保留数据记录,但通过标记方式使该记录对外表现为“删除”。这种方式应用很广,特别是需要备份、微信应用系统、查记存档时,通常不会真正将数据删掉。
本文将所有操作都培根于 SpringBoot + JPA,但有部分分析同样适用于 MyBatis 环境。
一、为什么要软删除?
常见需求:
需要查看删除历史仅允许某级别的用户删除,其他用户不能看见有定时删除执行过程(尽期删除)需要恢复刚被删除的记录
如果直接删除:repository.deleteById(id) 就导致数据丢失
因此:首选软删除,实现方式是在数据表中添加 deleted 标记。
二、基础实现:在 JPA 中通用 deleted 字段
1. 添加基组实体 BaseEntity
@MappedSuperclass
public abstract class BaseEntity {
@Column(name = "deleted", nullable = false)
private Boolean deleted = false;
public Boolean getDeleted() {
return deleted;
}
public void setDeleted(Boolean deleted) {
this.deleted = deleted;
}
}
各实体类继承 BaseEntity,即可使用 deleted 字段
2. Repository 中加入自定义删除
@Repository
public interface UserRepository extends JpaRepository
@Modifying
@Query("UPDATE User u SET u.deleted = true WHERE u.id = :id")
void softDelete(@Param("id") Long id);
List
}
将 deleteById() 的操作替换为 softDelete()
3. 全局查询增加 deleted 条件
如果是 Hibernate,可考虑 @Where
@Entity
@Table(name = "user")
@Where(clause = "deleted = false")
public class User extends BaseEntity {
// fields...
}
这样调用 findAll() 自动加上条件 deleted = false
三、MyBatis 环境如何实现?
在 MyBatis 中,需要手动编写 SQL:
UPDATE user SET deleted = 1 WHERE id = #{id};
SELECT * FROM user WHERE deleted = 0;
建议在 XML 中使用
四、扩展:如何实现微信类的 “删除后隐藏” 而非完全隐藏?
有时需要展示“已删除”状态(如微信社交中),我们可以通过加载 deleted = true 记录,分类处理:
List
List
List
或直接推荐使用 deleted 状态字段,缓解应用中的删除进度操作
五、实际项目应用经验
不要给完全所有实体都增加 deleted,依需选择无数据结构要求时不要乱用 deleted配合定时任务执行真正 delete 也是解决之道有处理旧数据迁移时,删除标记很有用
六、总结
软删除是 SpringBoot 项目中很重要的基础能力之一,不仅是收缩性数据的需求,更是对数据生命周期的一种考虑。
建议同学们在课程设计或毕业项目中优先实现这一能力。