有没有办法获得结果集的JPA命名查询的计数大小?

Tim*_*Tim 17 java jpa jpql

我喜欢JPA中的命名查询的概念我将要做的静态查询,但我经常想要查询查询的计数结果以及查询的某个子集的结果列表.我宁愿不写两个几乎相同的NamedQueries.理想情况下,我想拥有的是:

@NamedQuery(name = "getAccounts", query = "SELECT a FROM Account")
.
.
  Query q = em.createNamedQuery("getAccounts");
  List r = q.setFirstResult(s).setMaxResults(m).getResultList();
  int count = q.getCount();
Run Code Online (Sandbox Code Playgroud)

因此,假设m为10,s为0,并且Account中有400行.我希望r有一个包含10个项目的列表,但我想知道总共有400行.我可以写第二个@NamedQuery:

@NamedQuery(name = "getAccountCount", query = "SELECT COUNT(a) FROM Account")
Run Code Online (Sandbox Code Playgroud)

但是,如果我总是想要计算,这似乎是一种干扰.在这个简单的情况下,很容易保持两者同步,但如果查询发生变化,我必须更新两个@NamedQueries以保持值一致,这似乎不太理想.

这里的一个常见用例是获取项目的某些子集,但需要某种方式来指示总计数("显示1-10的400").

Tim*_*Tim 14

所以我最终使用的解决方案是创建两个@NamedQuerys,一个用于结果集,一个用于计数,但是在静态字符串中捕获基本查询以维护DRY并确保两个查询保持一致.所以对于上面,我有类似的东西:

@NamedQuery(name = "getAccounts", query = "SELECT a" + accountQuery)
@NamedQuery(name = "getAccounts.count", query = "SELECT COUNT(a)" + accountQuery)
.
static final String accountQuery = " FROM Account";
.
  Query q = em.createNamedQuery("getAccounts");
  List r = q.setFirstResult(s).setMaxResults(m).getResultList();
  int count = ((Long)em.createNamedQuery("getAccounts.count").getSingleResult()).intValue();
Run Code Online (Sandbox Code Playgroud)

显然,在这个例子中,查询体是微不足道的,这是过度的.但是对于更复杂的查询,您最终会得到查询主体的单一定义,并且可以确保您同步这两个查询.您还可以获得预编译查询的优势,至少使用Eclipselink,您可以在启动时进行验证,而不是在调用查询时进行验证.

通过在两个查询之间进行一致的命名,可以通过基于查询的基本名称来包装代码的主体以运行两个集合.


Pas*_*ent 5

使用setFirstResult/ setMaxResults千万不能返回结果集的一个子集,查询甚至还没有当你调用这些方法运行,它们会影响调用时将执行的生成SELECT查询getResultList.如果要获取总记录数,则必须SELECT COUNT在单独的查询中(通常在分页之前)对实体进行处理.

有关完整示例,请使用JSF,Catalog Facade Stateless Session和Java Persistence API查看示例应用程序中的数据集分页.