2015-05-23 82 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();