子查询

时间:2015-05-23 12:20:29

标签: sql hibernate jpa hql limit

首先,我想指出,我知道如何使用LIMIT在SQL中执行此操作,但因为JPQL不允许LIMIT关键字,因此我的问题:

我有一个返回地点及其链接标签的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因为我返回标签所以我不知道有多少行等等。

在SQL中我会做这样的事情

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

我会做一个子查询并在那里使用LIMIT来选择我想要的地方。

但是因为JPQL不允许LIMIT,所以我现在所做的是第二次数据库调用来检索我想要的placeIds并使用entityManager setMaxResult。限制。然后我将这些ID提供给另一个查询。

对JPA更有经验的人能告诉我这是一个好习惯吗?有没有其他方法可以做这些事情,而不必进行2次分离的数据库调用?

Ps:我在查询中直接选择t.tagName的原因是因为集合PlaceTag(在Place实体内)是LAZILY初始化的,如果我在java中访问它会触发额外的数据库调用。我觉得我试过像这样使用JOIN FETCH:

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());
}

但我收到有关查询的错误:

  

查询指定的连接提取,但是提取的所有者   选择列表中没有关联

谢谢!

1 个答案:

答案 0 :(得分: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();