爲了避免每次在查詢的時候加上是否刪除字段,做了一下封裝。
@NoRepositoryBean @RepositoryRestResource(exported = false) public interface BaseRepository<T extends BaseEntity, IdT extends Long> extends JpaRepository<T, IdT> { @Query( value = "update #{#entityName} set deletedAt=current_timestamp where id = ?1 " + "and deletedAt is null") @Transactional @Modifying void delete(IdT id); @Override @Transactional default void delete(T entity) { delete((IdT) entity.getId()); } @Transactional default void delete(Iterable<? extends T> entities) { entities.forEach(entitiy -> delete((IdT) entitiy.getId())); } @Override @Query(value = "update #{#entityName} set deletedAt=current_timestamp where deletedAt is null ") @Transactional @Modifying void deleteAll(); @Query( value = "update #{#entityName} set deletedAt=current_timestamp where id in ?1 " + "and deletedAt is null ") @Transactional @Modifying void deleteInBatch(List<IdT> ids); }
@NoRepositoryBean 使用了該註解的接口不會被單獨創建實例,只會作爲其他接口的父接口而被使用。 deletedAt 是否刪除字段
@MappedSuperclass @Data public abstract class BaseEntity { private Timestamp deletedAt; public abstract Long getId(); }
@MappedSuperclass 通過這個註解,我們可以將該實體類當成基類實體,它不會隱射到數據庫表,但繼承它的子類實體在隱射時會自動掃描該基類實體的隱射屬性,添加到子類實體的對應數據庫表中。
@Data @Entity @Table(name = "indeed_api_keys") @Where(clause = "deleted_at is null") @NoArgsConstructor public class IndeedApiKey extends BaseEntity implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String key; private static final long serialVersionUID = 1866497302444576352L; }
實體繼承BaseEntity,並加上 @Where(clause = "deleted_at is null")
public interface EmailMessageRepository extends BaseRepository<EmailMessage, Long> { List<EmailMessage> findAllByApplicationId(Long applicationId); @Query( value = "SELECT * FROM email_messages e WHERE e.deleted_at IS NULL AND " + "lower(?1)=lower(e.email_hash) ORDER BY e.created_at DESC", nativeQuery = true) List<EmailMessage> findByEmailHash(String emailHash); }
Repository繼承BaseRepository
這樣配置之後,若使用jpa默認的查詢,就會自動加上 deleted_at is null的過濾條件。但當你重寫jpa默認的查詢機制,還是需要手動加上deleted_at is null的過濾條件。