gpt4 book ai didi

java - 在 Spring Data JPA 存储库中使用 EntityGraph 进行过滤

转载 作者:太空宇宙 更新时间:2023-11-04 12:26:18 26 4
gpt4 key购买 nike

我有一个与 ListingAttachment 具有一对多关系的 Listing 表。现在在整个应用程序中,每个表/实体都有 deleteFlag 并且每个存储库应该仅使用 deleteFlag 0 来获取数据。所以基本上,我们不会删除任何数据,只是将 deleteFlag 标记为 1。

以下是我的实体结构:

列表.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 相关实体上过滤或应用条件。

例如,在我的例子中,我应该使用 deleteFlag 0 及其所有附件 (ListingAttachments) 获取 Listing,而 deleteFlag 也必须具有 deleteFlag 0。使用如上面存储库中所示的 EntityGraph,它会获取所有附件,而不管 deleteFlag。有什么方法可以根据 deleteFlag 过滤附件吗?

最佳答案

EntityGraph 定义应获取(急切或惰性)实体的哪些属性或(子)图,而不必在实体本身上定义它们。

在 JPA 2.0(没有 EntityGraph)中,您必须在实体处定义是否要使用 FetchType.LAZY(默认)或 FetchType.EAGER 来加载关系,并且始终使用此模式。

使用 EntityGraph,您可以定义每个查询的属性和(子)图。

EntityGraph不用于过滤元素。

如果您想要查找未标记为已删除 (delete flag = 0) 且至少有一个 ListingAttachment 未标记为已删除的 Listings,您可以使用 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,因为您无法使用 listingAttachments 集合直接取消引用 JPA 查询中的 deleteFlag

以上示例会返回所有未标记为已删除的列表,并且至少有一个未标记为已删除的 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")

关于java - 在 Spring Data JPA 存储库中使用 EntityGraph 进行过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38356565/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com