3

我正在编写一个 J2EE/JPA/Spring 3 应用程序,试图保持纯 JPA 2.0。我想获得子对象的计数而不必加载它们,因为这显然是一项昂贵的操作。例如这里是一个简化的例子

Organisation
 - OrgID
 - OrgName

Employee
 - EmployeeID
 - OrgID (key to Organisation table)
 - EmployeeName

在 jsp 页面上,我想显示所有组织的列表和员工人数的计数,而无需自己加载员工。如果它可以是加载所有组织对象并以某种方式加载员工对象的计数的单个数据库命中,那就太好了。我宁愿避免一个查询列出组织,然后每个组织一个查询来计算员工。我想我可以添加一个瞬态属性来保存计数,我不确定如何最好地做到这一点。

只是为了给出规模的概念,将有大约 50 个组织,每个组织将有 0 到 500 名员工。我宁愿避免任何特定于实现的扩展,因为我已经更改过一次 JPA 提供程序并且可能会再次更改。

在 SQL 中,我只是进行连接、分组和计数,但我不知道如何在 JPA 中进行。任何帮助表示赞赏!

4

2 回答 2

4

您可以直接选择到您定义为保存组织和计数的结果的对象。然后,您只需编写查询。唯一的技巧是您必须手动按组织上的每个字段进行分组。“按组织分组”是不合法的。

public class OrgWithEmpCount {
  private Organisation org;
  private Long empCount;
  public OrgWithEmpCount(Organisation org, Long empCount) {
    this.org = org;
    this.empCount = empCount;
  }
}


Select new full.package.OrgWithEmpCount(o, count(e.employeeId)) 
from Organisation o, IN(o.employees) e 
group by o.orgId, o.orgName, o.whateverElse
于 2012-07-27T06:54:01.700 回答
2

Going off of the the accepted answer from Affe - this worked except for the case of you wanting to have the count for companies even with no employees. The IN query will end up just excluding those companies. Hard to imagine a company with zero employees, but for the sake of the Query example, you could do it like this:

select new full.package.OrgWithEmpCount(o, count(e.employeeId))
FROM Organisation o LEFT JOIN e.employees AS e
group by o.orgId, o.orgName, o.whateverElse

You get the idea... just instead of doing an IN, do a LEFT JOIN.

于 2013-04-05T14:40:22.337 回答