![](/img/trans.png)
[英]Spring Data JPA + JpaSpecificationExecutor + EntityGraph
[英]Filtering using EntityGraph in Spring Data JPA Repository
我有一個Listing
表至極有一與多的關系ListingAttachment
。 現在在整個應用程序中,每個表/實體都有deleteFlag
,每個存儲庫只能使用deleteFlag
0獲取數據。所以基本上,我們不會刪除任何僅將deleteFlag標記為1的數據。
以下是我的實體結構:
Listing.java
@Entity
public class Listing {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
String title;
String description;
@OneToMany(mappedBy = "listing", cascade={CascadeType.ALL})
private Set<ListingAttachment> listingAttachments;
private int deleteFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(int deleteFlag) {
this.deleteFlag = deleteFlag;
}
public Set<ListingAttachment> getListingAttachments() {
return listingAttachments;
}
public void setListingAttachments(Set<ListingAttachment> listingAttachments) {
this.listingAttachments = listingAttachments;
}
public ListingAttachment addListingAttachment(ListingAttachment listingAttachment) {
getListingAttachments().add(listingAttachment);
listingAttachment.setListing(this);
return listingAttachment;
}
public ListingAttachment removeListingAttachment(ListingAttachment listingAttachment) {
getListingAttachments().remove(listingAttachment);
listingAttachment.setListing(null);
return listingAttachment;
}
}
ListingAttachment.java
@Entity
public class ListingAttachment {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
String fileName;
@ManyToOne
@JoinColumn(name = "LISTING_ID")
private Listing listing;
private int deleteFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public Listing getListing() {
return listing;
}
public void setListing(Listing listing) {
this.listing = listing;
}
public int getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(int deleteFlag) {
this.deleteFlag = deleteFlag;
}
}
ListingRepository.java
public interface ListingRepository extends JpaRepository<Listing, Long> {
@EntityGraph(attributePaths = { "listingAttachments" })
@Query("SELECT l FROM Listing l WHERE l.id = (:id) and deleteFlag = 0")
public ListingfindOneWithImagesAndAttachments(@Param("id") Long id);
}
使用EntityGraph,我們可以輕松獲取OneToMany實體。 但問題是如何在Many
相關實體上過濾或應用條件。
對於例如,在我的情況,我應該取Listing
與deleteFlag
0及其所有附件(ListingAttachments),這反過來也必須有deleteFlag
0。使用EntityGraph
如上面的資料庫,它提取不管所有附件deleteFlag
。 有什么辦法可以根據deleteFlag
過濾附件嗎?
EntityGraph定義了實體的哪些屬性或(子)圖應該被提取(急切或懶惰),而不必在實體本身上定義它們。
在JPA 2.0(沒有EntityGraph)中,您必須在實體中定義是否要使用FetchType.LAZY
(默認值)或FetchType.EAGER
來加載關系,並始終使用此模式。
使用EntityGraph,您可以為每個查詢定義屬性和(子)圖。
EntityGraph不用於過濾元素。
如果您要查找的Listings
為刪除未標明( delete flag = 0
),並且至少有一個ListingAttachment
沒有被標記為刪除,你可以通過使用一個做到這一點FETCH JOIN
public interface ListingRepository extends JpaRepository<Listing, Long> {
@EntityGraph(attributePaths = { "listingAttachments" })
@Query("SELECT l FROM Listing l JOIN l.listingAttachments a
WHERE l.id = (:id) and l.deleteFlag = 0 and a.deleteFlag = 0")
public Listing findOneWithImagesAndAttachments(@Param("id") Long id);
}
你需要加入ListingAttachments
,因為你不能直接取消引用deleteFlag
使用的JPA查詢listingAttachments
收藏。
上面的示例返回所有未標記為已刪除的列表,並且至少有一個未標記為已刪除的ListingAttachment。
如果要返回未標記為已刪除但可能沒有ListingAttachments的列表,則必須將其更改為LEFT OUTER JOIN
@Query("SELECT l FROM Listing l
LEFT OUTER JOIN l.listingAttachments a
WHERE l.id = (:id) and l.deleteFlag = 0 and a.deleteFlag = 0")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.