Jpa實現邏輯刪除


Spring Data 是個好東西,極大簡化了后端dao的操作,只需要在 dao 接口寫個 findByXXX 的方法就能自動實現按條件查詢這個簡直太爽了。但是在實際使用過程中,可能會遇到一個持久化邏輯刪除的問題。那么問題來了。spring data jpa並不支持邏輯刪除。那如何處理?

 

在互聯網項目中,通常刪除都不是物理刪除,而是邏輯刪除

 

那么在展示數據的時候需要過濾掉已刪除的數據。而@Where 注解可以說就是為此而設計的。

package org.hibernate.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * Where clause to add to the element Entity or target entity of a collection.  The clause is written in SQL.
 * A common use case here is for soft-deletes.
 *
 * @author Emmanuel Bernard
 */
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface Where {
    /**
     * The where-clause predicate.
     */
    String clause();
}

 

 

 這玩意兒乍一看很美好。但是實際不然。這樣做將所有的刪除方法都覆蓋了。當我想要用到物理刪除的時候。就不能用了。於是再次出發。尋找一種更加美妙的解決方案。終於讓我找到了。話不多說。直接放碼。

@NoRepositoryBean
public interface BaseDao<T extends BaseEntry, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
 
    @Override
    @Transactional(readOnly = true)
    @Query("select e from #{#entityName} e where e.deleted = false")
    List<T> findAll();
 
    @Override
    @Transactional(readOnly = true)
    @Query("select e from #{#entityName} e where e.id in ?1 and e.deleted = false")
    Iterable<T> findAll(Iterable<ID> ids);
 
    @Override
    @Transactional(readOnly = true)
    @Query("select e from #{#entityName} e where e.id = ?1 and e.deleted = false")
    T findOne(ID id);
 
    @Override
    @Transactional(readOnly = true)
    @Query("select count(e) from #{#entityName} e where e.deleted = false")
    long count();
 
    @Override
    @Transactional(readOnly = true)
    default boolean exists(ID id) {
        return findOne(id) != null;
    }
 
    @Query("update #{#entityName} e set e.deleted = true where e.id = ?1")
    @Transactional
    @Modifying
    void logicDelete(ID id);
 
    @Transactional
    default void logicDelete(T entity) {
        logicDelete((ID) entity.getId());
    }
 
    @Transactional
    default void logicDelete(Iterable<? extends T> entities) {
        entities.forEach(entity -> logicDelete((ID) entity.getId()));
    }
 
    @Query("update #{#entityName} e set e.deleted = true ")
    @Transactional
    @Modifying
    void logicDeleteAll();
}

BaseEntry代碼如下:

    @Data
    @MappedSuperclass
    public class BaseEntry implements Serializable {
     
        private static final long serialVersionUID = 5966306766659220492L;
     
        @Id
        protected String id;
     
        @Temporal(TemporalType.TIMESTAMP)
        protected Date createdDate;
     
        protected String createdBy;
     
        @Temporal(TemporalType.TIMESTAMP)
        protected Date updatedDate;
     
        protected String updatedBy;
     
        protected Boolean deleted = false;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM