2015-05-23 83 views
1

首先使用時,我想指出,我知道我怎麼能在SQL做到這一點通過使用限制,但因爲JPQL不允許LIMIT關鍵字所以我的問題:JPA和JPQL限制子查詢

我有JPQL查詢返回的地方,他們的鏈接標籤:

List<Object[]> p = entityManager.createQuery(" 
SELECT p, t.tagName 
FROM Place p LEFT JOIN .... ... 

例如,這可能返回 PLACE1 | tag1 place1 | tag2 place1 | tag3 place2 | tag1 place2 | TAG4

現在..我顯然不能簡單地恢復整個數據庫的地方..我不能簡單地把一個LIMIT在任務結束,因爲IM返回代碼,因此我並不怎麼有多少行等。

在SQL我會做這樣的事情

SELECT p.name, t.tag_name FROM ... WHERE p.idPlace IN (SELECT p.idPlace FROM ... WHERE... LIMTI 10); 

我會做一個子查詢和使用限制那裏只能選擇我想要的地方。

但是由於JPQL不允許LIMIT,因此我現在所做的是第二次數據庫調用來檢索我想要的placeIds並使用entityManager setMaxResult。限制。然後我將這些ID提供給其他查詢。

有人更有經驗的JPA告訴我這是一種好的做法嗎?有沒有其他的方式做事情,而不必做2分離的數據庫調用?

ps:我在查詢中直接選擇t.tagName的原因是因爲集合PlaceTag(Place實體內部)是LAZILY初始化的,如果我在java中訪問它,它將觸發額外的數據庫調用。難道我曾嘗試使用連接抓取這樣的:

List<Place> places = entityManager.createQuery("" + 
       "SELECT p FROM Place p " + 
       "JOIN FETCH p.PlaceTag pt " + 
       "JOIN FETCH pt.tag t").setMaxResults(10).getResultList(); 

所以我可以做在Java中是這樣(無需訪問p.getPlaceTag()和getTag()

for (Place p : places) { 
    for (PlaceTag pt: p.getPlaceTag()) 
     System.out.println(pt.getTag().getTagName()); 
} 
時觸發一個新的數據庫

但我得到這個查詢的錯誤:

查詢指定連接抓取,但所取得的 協會的老闆是不存在於選擇列表

謝謝!

回答

0
String query = "SELECT p FROM Place p " 
        + "JOIN p.PlaceTag pt " 
        + "JOIN pt.tag t"; 
List<Place> places = entityManager.createQuery(query) 
         .setMaxResults(10) 
         .setFirstResult((pageNumber-1) * pageSize) 
         .getResultList();