之前寫過關於springboot~jpa優雅的處理isDelete的默認值的文章,今天説一下在jpa或者其它類型的Repository中實現軟刪除的方法,主要藉助了自定義的倉儲的能力。
優雅的引用方式
/**
* 開啓軟刪除的能力
*
* @author lind
* @date 2025/9/8 11:24
* @since 1.0.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@EnableJpaRepositories(repositoryBaseClass = SoftDeleteRepositoryImpl.class)
public @interface EnableSoftDeleteRepository {
}
接口標準化
/**
* 軟刪除能力,通過@EnableSoftDeleteRepository註解開啓功能,通過接口繼承的方式實現這個能力
*
* @param <T>
* @param <ID>
*/
@NoRepositoryBean // 不讓jpa使用代理建立實現類
public interface SoftDeleteRepository<T, ID> {
T getEntityById(ID id);
/**
* 希望重寫findById方法
* @param id
* @return
*/
T getById(ID id);
}
覆蓋默認的deleteById方法,實現軟刪除
/**
* 自定義的公共倉儲的實現
*
* @param <T>
* @param <ID>
*/
public class SoftDeleteRepositoryImpl<T, ID> extends SimpleJpaRepository<T, ID> implements SoftDeleteRepository<T, ID> {
private final EntityManager entityManager;
private final JpaEntityInformation<T, ID> jpaEntityInformation;
Class<T> domainType;
Logger logger = LoggerFactory.getLogger(SoftDeleteRepositoryImpl.class);
public SoftDeleteRepositoryImpl(JpaEntityInformation<T, ID> jpaEntityInformation, EntityManager entityManager) {
super(jpaEntityInformation, entityManager); // 必須調用父類構造函數
this.entityManager = entityManager;
this.jpaEntityInformation = jpaEntityInformation;
this.domainType = jpaEntityInformation.getJavaType();
}
@Override
public T getEntityById(ID id) {
return entityManager.find(this.domainType, id);
}
/**
* @param id
* @deprecated
*/
@Override
public void deleteById(ID id) {
logger.info("CustomRepositoryImpl.getById " + id);
T entity = getEntityById(id);
if (entity != null && entity instanceof DeletedFlagField) {
((DeletedFlagField) entity).setDeletedFlag(1);
entityManager.merge(entity);
}
else {
super.deleteById(id);
}
}
}
需要實現軟刪除的倉庫接口上,繼承這個接口即有這個軟刪除的能力
/**
* 用户倉儲
*
* @author lind
* @date 2025/7/15 15:56
* @since 1.0.0
*/
public interface UserEntityRepository extends SoftDeleteRepository<UserEntity, String>,
JpaRepository<UserEntity, String>, JpaSpecificationExecutor<UserEntity> {
}