软删除(Soft Delete)是一种数据删除策略,它不是在数据库中物理删除记录,而是通过标记记录为"已删除"状态来实现逻辑删除。与硬删除(Hard Delete)相比,软删除保留了数据的历史记录,便于数据恢复和审计。
这是最简洁的实现方式之一:
@Entity
@Table(name = "users")
@SQLDelete(sql = "UPDATE users SET deleted = true WHERE id = ?")
@Where(clause = "deleted = false")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private boolean deleted = false;
// getters and setters
}
@Entity
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;
private boolean deleted;
@PreRemove
public void preRemove() {
this.deleted = true;
}
// getters and setters
}
更灵活的方式是创建自定义Repository:
public interface SoftDeleteRepository<T, ID> extends JpaRepository<T, ID> {
@Query("update #{#entityName} e set e.deleted = true where e.id = ?1")
@Modifying
@Transactional
void softDelete(ID id);
@Query("select e from #{#entityName} e where e.deleted = false")
List<T> findAllActive();
}
然后让你的Repository继承这个接口:
public interface UserRepository extends SoftDeleteRepository<User, Long> {
// 自定义查询方法
}
原因:没有在查询中过滤已删除的记录
解决方案:
@Where
注解自动过滤deleted = false
条件原因:软删除不是真正的删除操作
解决方案:
@PreRemove
回调处理关联实体原因:标记为删除的记录仍然参与唯一约束检查
解决方案:
UNIQUE (name, deleted)
// 实体类
@Entity
@Table(name = "employees")
@SQLDelete(sql = "UPDATE employees SET deleted = true WHERE id = ?")
@Where(clause = "deleted = false")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String email;
private String name;
private boolean deleted = Boolean.FALSE;
// getters and setters
}
// 自定义Repository接口
@NoRepositoryBean
public interface SoftDeleteCrudRepository<T, ID> extends CrudRepository<T, ID> {
@Query("UPDATE #{#entityName} e SET e.deleted = true WHERE e.id = ?1")
@Modifying
@Transactional
void softDeleteById(ID id);
@Query("SELECT e FROM #{#entityName} e WHERE e.deleted = false")
Iterable<T> findAllActive();
@Query("SELECT e FROM #{#entityName} e WHERE e.deleted = true")
Iterable<T> findAllInactive();
}
// 服务层使用
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public void deleteEmployee(Long id) {
employeeRepository.softDeleteById(id);
}
public List<Employee> getAllActiveEmployees() {
return employeeRepository.findAllActive();
}
}
通过以上方法,你可以在Spring API中实现灵活可靠的软删除功能。
没有搜到相关的文章