3.1 映射依赖实体
在 SQL 中,您可以使用 JOIN 编写查询。可以在 HQL 中做同样的事情吗?简短的回答是肯定的。但完整的答案会更有趣。
首先,当我们在 SQL 中编写 JOIN 时,通常意味着一个表引用另一个表。例如,task 表包含一个 employee_id 列,该列引用 employee 表的 id 列。
这种依赖性可以在 Hibernate 中使用注解来描述。首先,让我们为表创建实体。首先,让我们描述一下员工表:
@Entity @Table(name="employee")
class Employee {
@Column(name="id")
public Integer id;
@Column(name="name")
public String name;
@Column(name="salary")
public Integer salary;
@Column(name="join_date")
public Date joinDate;
}
任务表的EmployeeTask类:
@Entity @Table(name="task")
class EmployeeTask {
@Column(name="id")
public Integer id;
@Column(name="name")
public String name;
@Column(name="employee_id")
public Integer employeeId;
@Column(name="deadline")
public Date deadline;
}
一切都很好,但有一个建议。我们来看最后一个例子中的employeeId字段:
@Column(name="employee_id")
public Integer employeeId;
你注意到什么奇怪的事了吗?如果没有,那么这意味着你已经形成了SQL语言的思维方式。
问题是,在 Java 语言中,我们通常对这种依赖关系的描述略有不同:
public Employee employee;
我们不需要指定id,我们通常只指定一个变量来保存对Employee对象的引用。如果没有这样的对象,则存储null 。
而 Hibernate 允许我们使用注解来描述这样的情况:
@ManyToOne @JoinColumn(name="employee_id", nullable=true)
public Employee employee;
注释@ManyToOne
告诉 Hibernate 许多EmployeeTask实体可以引用一个Employee实体。
并且注释指定了从中获取id@JoinColumn
的列的名称。所有其他必要的信息将从 Employee 类的注释中获取。
最终结果将如下所示:
@Entity @Table(name="task")
class EmployeeTask
{
@Column(name="id")
public Integer id;
@Column(name="name")
public String name;
@ManyToOne @JoinColumn(name="employee_id", nullable=true)
public Employee employee;
@Column(name="deadline")
public Date deadline;
}
3.2 在HQL中使用join
现在让我们看看如何在 HQL 中编写对相关实体的查询。
第一种情况。
我们有一个员工(Employee),我们想得到他的任务列表。下面是该查询在 SQL 中的样子:
SELECT task.* FROM task JOIN employee ON task.employee_id = employee.id
WHERE employee.name = "Ivan Ivanovich";
现在让我们用 HQL 编写相同的查询:
from EmployeeTask where employee.name = "Ivan Ivanovich"
EmployeeTask类有一个employee字段,还有一个name字段,所以这个查询会起作用。
情况二。
返回有逾期任务的员工列表。下面是该查询在 SQL 中的样子:
SELECT DISTINCT employee.*
FROM task JOIN employee ON task.employee_id = employee.id
WHERE task.deadline < CURDATE();
DISTINCT
之所以使用,是因为可以将许多任务分配给一个用户。
现在让我们用 HQL 编写相同的查询:
select distinct employee from EmployeeTask where deadline < CURDATE();
此查询中的员工是EmployeeTask类的一个字段
情况三。
将所有未分配的任务分配给主管。SQL 查询将如下所示:
UPDATE task SET employee_id = 4 WHERE employee_id IS NULL
现在让我们用 HQL 编写相同的查询:
update EmployeeTask set employee = :user where employee is null
最后一个查询是最难的。我们需要传递 ID,director,但是 EmployeeTask 类不包含可以写入 id 的字段,而是包含一个 Employee 字段,您需要在该字段中分配对 Employee 类型对象的引用。
在 Hibernate 中,这个问题是在传递给 Query 对象的查询参数的帮助下解决的。而在 HQL 本身中,此类参数是通过冒号编写的::user
。但是我们稍后会讨论这个。
GO TO FULL VERSION