假設我們有一個非常基本的物體,比如Category。每個類別可以有零個或多個子類別(subcategories型別欄位Set<Category>)。我想獲取從給定根開始的整個類別樹。為此,我使用了一個公共表運算式,它回傳構成樹的類別(我單獨對其進行了測驗,它作業正常)。
有沒有辦法自動將此結果映射到一個根,Category包括任何級別的所有子類別?我知道我可以手動處理元組,但我很好奇是否有更優雅的方式。似乎@SqlResultSetMapping物體圖無法解決問題。
下面是一些簡化的代碼。首先,類別物體如下所示:
@Entity
@Table(name = "CATEGORY")
public class Categoryd {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name = "C_I_IDF")
protected Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="C_PARENTCATEGORY")
private CategoryEntity parentCategory;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "parentCategory", cascade = { CascadeType.MERGE, CascadeType.REMOVE })
@Fetch(value = FetchMode.SELECT)
@BatchSize(size=10)
private List<CategoryEntity> subCategories = new ArrayList<>();
}
我的遞回查詢是這樣的:
WITH categoryrecursive (id) AS (
SELECT C_I_IDF
FROM CATEGORY parent
WHERE parent.C_I_IDF = <some number>
UNION ALL
SELECT sub.C_I_IDF
FROM categoryrecursive, CATEGORY sub
WHERE sub.C_PARENTCATEGORY = categoryrecursive.id
)
SELECT cat.*
FROM categoryrecursive rc
INNER JOIN CATEGORY cat ON cat.C_I_IDF = rc.id
該查詢回傳從給定根開始的類別串列。
uj5u.com熱心網友回復:
由于 Hibernate 不知道(而且您也無法告訴它),所有這些subCategories都是“加載的”,因此您大致只有一個選項可以避免弄亂物件樹。
配置一個足夠大@BatchSize(size = 1000)的subCategories批量大小(例如 1000),以便延遲加載可以在一個查詢中加載所有集合。然后您可以使用@SqlResultSetMapping您擁有的查詢并觸發一個集合的初始化,以使用單個查詢初始化大多數/所有集合(除了您的遞回 CTE 查詢)。
這里的缺點是您需要第二個查詢,但是如果您不想自己在記憶體中重建樹,那是您能做的最好的事情。
我建議您加倍努力,使用自定義 DTO 甚至僅使用物體來實作自己的樹化。應該可以解決以下問題:
List<Category> list = ...
for (Category c : list) {
c.setSubCategories(new ArrayList<>());
}
Category root = null;
for (Category c : list) {
if (c.getParentCategory() == null) {
root = c;
continue;
}
c.getParentCategory().getSubCategories().add(c);
}
return root;
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/513208.html
