JPA - 计算列作为实体类属性?

And*_*eiM 6 database hibernate jpa java-ee

JPA比较新,所以我有一种架构问题.假设我有表EMPLOYEE和DEPARTMENT有多对一关系(即许多员工为一个部门工作):

EMPLOYEE
  EMPLOYEE_ID
  EMPLOYEE_NAME
  DEPARTMENT_ID 

DEPARTMENT
  DEPARTMENT_ID
  DEPARTMENT_NAME
Run Code Online (Sandbox Code Playgroud)

所以我可以为Employee和Department定义合适的实体,没有问题.但是,在一个视图中,我想显示具有该部门工作人员数量的部门列表,如下所示:

SELECT D.DEPARTMENT_NAME, 
       (SELECT COUNT(*) FROM EMPLOYEE E WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID) NUMBER_OF_EMPLOYEES
FROM DEPARTMENT D
Run Code Online (Sandbox Code Playgroud)

我只是不确定使用JPA实现此目的的正确策略是什么...我不想总是为Department实体获取员工数量,因为在需要时只有一个视图.

看起来Hibernate的@Formula是一种可能的方法,但是它不符合JPA标准.

Mat*_*ttR 4

您可以使用“new”语法在 QL 中创建任何对象 - 您的类只需要一个构造函数来获取查询返回的值。

例如,对于像 DepartmentEmployeeCount 这样的类,带有构造函数:

public DepartmentEmployeeCount(String departmentName, Integer employeeCount)
Run Code Online (Sandbox Code Playgroud)

你可以使用 QL 类似的东西:

SELECT NEW DepartmentEmployeeCount(D.DEPARTMENT_NAME, count(E.id)) from Department D left join D.employees E GROUP BY D.DEPARTMENT_NAME
Run Code Online (Sandbox Code Playgroud)

或者,如果您只是选择计数(*),您可以简单地将查询结果转换为数字。

或者,要在没有 DepartmentEmployeeCount 类的情况下执行相同的操作,您可以省略 NEW,因此:

SELECT D.DEPARTMENT_NAME, count(E.id)    
Run Code Online (Sandbox Code Playgroud)

这将返回一个List<Object[]>其中每个列表项都是一个由 2 个元素组成的数组:departmentName 和 count。

要回答您稍后在评论中提出的问题,要填充部门的所有字段以及临时员工计数字段,一个建议是执行 2 个查询。这仍然比您的原始查询(每个员工计数的子选择)更有效。

所以一个查询来读取部门

SELECT D from Department D
Run Code Online (Sandbox Code Playgroud)

给你一个List<Department>

然后第二个查询返回一个临时数组:

SELECT D.DEPARTMENT_ID, count(E.id) from Department D left join D.employees E GROUP BY D.DEPARTMENT_ID
Run Code Online (Sandbox Code Playgroud)

给你一个List<Object[]>DEPARTMENT_ID 并计入其中。

然后,您使用第二个列表来更新第一个列表上的瞬态计数属性。(您可以尝试选择 Map 以使查找更容易,但我认为这是 Hibernate 的一个功能)。