我有一個物體類,它有多個具有oneToMany關聯的子女:
public class A{
private Long id;
private String name;
@OneToMany(mappedBy = "A", fetch = FetchType.LAZY, cascade = CascadeType.ALL,
orphanRemoval = true)
private List< B>bList= new ArrayList<>()。
@OneToMany(mappedBy = "A", fetch = FetchType.LAZY, cascade = CascadeType.ALL,
orphanRemoval = true)
private List< C>cList= new ArrayList<>()。
@OneToMany(mappedBy = "A", fetch = FetchType.LAZY, cascade = CascadeType.ALL,
orphanRemoval = true)
private List< D>dList= new ArrayList<>()。
//getters和setters。
}
對于B、C和D,我設定了ManyToOne。一句話,它們是雙向的關系。
現在,如果我通過id來獲取A,我看到大量的查詢被觸發,這變成了N 1的問題。為了解決這個問題,我在上面所有的oneToMany關系中添加了@Fetch(FetchMode.SUBSELECT),這導致較少的查詢被觸發。
我的問題是:
使用
@Fetch(FetchMode.SUBSELECT)可以嗎,或者我可以進一步優化它?如果我想通過呼叫findAll()方法來獲取所有的 "As "怎么辦?對于多個孩子的語法應該是什么?比如說
"select a from A a join fetch a.b then ?"
List< A > findAll()
我的問題是
uj5u.com熱心網友回復:
現在,如果我通過id來獲取A,我看到大量的查詢被觸發,這變成了N 1的問題。為了解決這個問題,我在上面的所有oneToMany關系中添加了@Fetch(FetchMode.SUBSELECT),這導致了更少的查詢被觸發。
你沒有說這些查詢是如何/何時被觸發的,所以問題的一個可能原因是你正在從你的 HTTP 端點回傳物體,然后被序列化。使用@Fetch(FetchMode.SUBSELECT)是 "提高 "性能的一種方法,但只有在您用來獲取A的基本查詢是簡單的情況下才能很好地作業。如果它變得太復雜(分頁,復雜的謂詞,等等),你應該堅持使用默認的SELECT,而不是通過@BatchSize( size = 32 )注釋配置一個適當的批處理大小。批量大小的一個好的值是你希望回傳的A實體的數量,這樣每個集合就只執行一個查詢。如果你允許的最大頁面大小是50,那么你將這個值設定為50將是完美的。
List< A > findAll()
如果你關心性能和可用性的話,千萬不要這么做。允許回傳所有元素的做法很少有意義,因為無論如何沒有用戶能夠一次處理超過~20個元素。正如之前所提到的,總是對頁面大小有某種上限,以防止可能導致性能問題的誤用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/327148.html
標籤:
