首先,我想指出,我知道如何使用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());
}
但我收到有关查询的错误:
查询指定的连接提取,但是提取的所有者 选择列表中没有关联
谢谢!
答案 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();