簡體   English   中英

用於檢索復雜實體的高效JPQL查詢

[英]Efficient JPQL query for retrieving complex entities

我是JPA / JPQL的新手,所以如果這個問題不清楚,請原諒。

我試圖找到一個有效的JQPL查詢,以獲取復雜對象的所有記錄。

(即由多個表表示,具有多個一對多關系 - 請參閱下面的簡化示例):

class ComplexObject {
    private Set< SubOject1> so1 ...
    .....
    @OneToMany(fetch = FetchType.LAZY)
    public Set< SubOject1>...
}

class SubObject1 {
    private Set< SubOject2> so2 ...
    .....
    @OneToMany(fetch = FetchType.LAZY)
    public Set< SubOject2>...
}

我使用以下JPQL查詢:

select distinct CO 
from ComplexObject CO 
left join fetch CO.so1 SO1 
left join fetch SO1.so2

查詢在無狀態會話上運行,以便獲得DB中當前數據的事實上的快照,該快照與實體管理器分離(因此使用左連接提取)。

不幸的是,我遇到了兩個問題:

  1. 由於復雜對象包含so1的多個實例,並且每個so1實例包含so2的多個實例,因此對SQL查詢的基礎轉換會為所有表連接的每一行產生一個特定的選擇查詢 - 這是一個非常浪費的解決方案。 有沒有辦法減少內部選擇查詢的數量? (這似乎是可怕的N + 1查詢問題)。

  2. JPQL查詢在所有表連接的產品上為每個內部SQL查詢返回一個ComplexObject實例 - 這意味着對ComplexObject實例的多個引用。 為什么會在'select distinct'查詢中發生這種情況?

我使用的JPA框架是hibernate,而DB是HyperSQL。

(1)問題與使用p6spy日志框架有關,該框架打印出來自大型數據庫表的所有結果。 日志記錄格式導致錯誤的假設,即許多查詢正在執行。

在嘗試微調性能時,使用本機查詢似乎沒有比使用JPQL查詢更好的性能。 使用本機查詢還會導致對象類型的結果,這需要后期處理。

您可以使用“查看對象”僅接收所需的列:

StringBuilder sb = new StringBuilder();
sb.append(" SELECT new ").append(ObjectVO.class.getName()).append("(co.someInfo1, co.someInfo2, so1.someInfo )");
sb.append(" FROM ComplexObject co ");
sb.append(" JOIN co.subOject1s so1 ");
sb.append(" LEFT JOIN so1.so2 so2 ");
sb.append(" WHERE so1.id = :idSo1 AND so2 = :someThing");

Query q = em.createQuery(sb.toString());
q.setParameter("idSo1", idSo1);
q.setParameter("someThing", someThing);

List<ObjectVO> listResult = q.getResultList();

ObjectVO類:

public class ObjectVO {

    private String info1;
    private Long info2; 
    private String info3;

    public PedidoModel(String info1, Long info2, String info3){
        this.info1 = info1;
        this.info2 = info2;
        this.info3 = info3;
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM