我正在研究采访中提出的一个常见问题。请获取经理信息,即经理的ID,姓名和向他报告的员工总数。
只有一张桌子
GS_Employee
如下,
-- Creation of Employeee table
create table GS_EMPLOYEE(
emp_id number(3) primary key,
emp_name varchar2(100),
division_id number (3) references GS_DIVISION,
manager_id number(3) references GS_EMPLOYEE
)
请忽略'GS_Division'表映射。从上表中,您将看到employee表也保存了经理的信息,因为manager也是雇员。因此,列“ manager_id”引用的是同一张表
manager_id number(3) references GS_EMPLOYEE
如果我编写普通的SQL查询,则自我联接将为我提供如下所示的期望结果,
select em.emp_id,
em.emp_name,
mgr.TOTAL_JUNIORS
from GS_EMPLOYEE em,
(select e2.emp_id as EMPLOYEE_ID,
count(e1.emp_id) as TOTAL_JUNIORS
from GS_EMPLOYEE e1,
GS_EMPLOYEE e2
where e1.manager_Id = e2.emp_id
group by (e2.emp_id)
) mgr
where em.emp_id = mgr.EMPLOYEE_ID;
但是,我需要使用Hibernate解决以上问题
因此我创建了一个实体
@Entity
@Table(name="GS_EMPLOYEE")
@NamedQuery(name="getAllEmployeesQuery",query ="from Employee e order by e.employeeId asc")
public class Employee implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1035435388896L;
@Id
@Column(name="EMP_ID")
private Integer employeeId;
@Column(name="EMP_NAME")
private String employeeName;
@ManyToOne(fetch=FetchType.LAZY,targetEntity=Division.class)
@JoinColumn(name="DIVISION_ID")
private Division division;
@ManyToOne(fetch=FetchType.LAZY,targetEntity=Employee.class)
@JoinColumn(name="MANAGER_ID")
private Employee manager;
@OneToMany(fetch = FetchType.LAZY,targetEntity=Employee.class,mappedBy="manager",cascade= {CascadeType.ALL},orphanRemoval=false)
private Set<Employee> employeeList;
在我的EmployeeDAOImpl.java类中,我编写了方法
public List<Employee> getManagerAndJuniors() throws Exception{
Session session = this.sessionFactory.getCurrentSession();
Query<Employee> q = session.getNamedQuery("getAllEmployeesQuery");
List<Employee> list = q.list();
return list;
}
以上方法获取所有员工,
现在在服务层中,即EmployeeServiceImpl.java,我进行过滤,
public List<Employee> getManagerAndJuniors() throws Exception{
List<Employee> managerList = this.dao.getManagerAndJuniors();
List<Employee> list = new ArrayList<Employee>();
managerList.forEach((Employee mgr) -> {
Set<Employee> empList = null;
try {
empList = mgr.getEmployeeList();
if(empList != null && empList.size() > 0) {
list.add(mgr);
}
}catch(Exception e) {
System.out.println(e.getMessage());
}
});
return list;
}
现在,我可以过滤所有添加到新列表中的管理器,然后返回。
我可以执行一些JPQL或休眠查询来解决与普通SQL查询中相同的问题。
我正在使用Oracle作为数据库。
Hql在from
子句中不支持子查询。 https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch16.html#queryhql-subqueries
注意句子:
请注意,HQL子查询只能在select或where子句中发生。
为什么不使用此查询而不使用子查询:
select manager.emp_id, manager.emp_name, count(*) as TOTAL_JUNIORS
from GS_EMPLOYEE manager
inner join GS_EMPLOYEE employee on manager.emp_id = employee.manager_id
where manager.manager_id = manager.emp_id
group by emp_id, emp_name;