表级关系

让我们再看看我们的两个表:

ID 姓名 职业 薪水 年龄 加入日期
1个 伊万诺夫伊万 程序员 100000 25 2012-06-30
2个 彼得罗夫彼得 程序员 80000 23 2013-08-12
3个 伊万诺夫谢尔盖 测试员 40000 三十 2014-01-01
4个 拉比诺维奇·莫伊沙 导演 200000 35 2015-05-12
5个 基连科阿纳斯塔西娅 办公室主管 40000 25 2015-10-10
6个 瓦斯卡 1000 3个 2018-11-11

员工表:

该表包含以下列:

  • 标识符整数
  • 名称VARCHAR
  • 职业VARCHA
  • 薪水整数
  • 年龄整数
  • join_date日期

这就是包含员工任务的任务表的样子:

ID emploee_id 姓名 最后期限
1个 1个 修复一个前端bug 2022-06-01
2个 2个 修复后端的一个bug 2022-06-15
3个 5个 买咖啡 2022-07-01
4个 5个 买咖啡 2022-08-01
5个 5个 买咖啡 2022-09-01
6个 (无效的) 打扫办公室 (无效的)
7 4个 享受生活 (无效的)
8个 6个 享受生活 (无效的)

该表只有 4 列:

  • id是任务的唯一编号(和表中的行)。
  • employee_id - 任务分配给的员工表中员工的 ID。
  • 名称- 任务的名称和描述。
  • deadline - 任务必须完成的时间。

任务表中的多行可以引用员工表中的单个条目。这种表级关系称为一对多

与 Java 类级别的关系

还有我们的班级,Employee班级:

@Entity
@Table(name="user")
class Employee {
   @Column(name="id")
   public Integer id;

   @Column(name="name")
   public String name;

   @Column(name="occupation")
   public String occupation;

   @Column(name="salary")
   public Integer salary;

   @Column(name="join_date")
   public Date join;
}

以及原始形式的EmployeeTask类:

@Entity
@Table(name="task")
class EmployeeTask {
   @Column(name="id")
   public Integer id;

   @Column(name="name")
   public String description;

   @Column(name="employee_id")
   public Integer employeeId;

   @Column(name="deadline")
   public Date deadline;
}

@OneToMany 注解

我们可以用不同的方式安排实体类之间的通信。

还记得我们用来在父类中创建子对象集合的@ElementCollection注解吗?类似的事情可以用@OneToMany annotation完成。只有这一次,Employee类将被更改:

@Entity
@Table(name="user")
class Employee {
   @Column(name="id")
   public Integer id;

   @OneToMany(cascade = CascadeType.ALL)
   @JoinColumn(name = "employee_id")
   private Set<EmployeeTask> tasks = new HashSet<EmployeeTask>();
}

使用@OneToMany注释,我们指出对象员工可以存储许多EmployeeTask对象。此外,使用@JoinColumn注释,我们指示对象 ID 存储在任务表的哪一列中员工.

但是,EmployeeTask类通常不包含引用 employee_id 列的字段。例子:

@Entity
@Table(name="task")
class EmployeeTask {
   @Column(name="id")
   public Integer id;

   @Column(name="name")
   public String description;

   @Column(name="deadline")
   public Date deadline;
}

employee_id 字段被认为是一个服务字段,它的值由 Hibernate 控制。

请求示例

如果你想给某个 worker 添加一些任务,那么你需要编写如下代码:

EmployeeTask task1 = new EmployeeTask();
task1.description = "Do Something Important";
session.persist(task1);

EmployeeTask task2 = new EmployeeTask();
task2.description = "Nothing to do";
session.persist(task2);
session.flush();

Employee director = session.find(Employee.class, 4);
director.tasks.add(task1);
director.tasks.add(task2);

session.update(director);
session.flush();

首先我们创建两个EmployeeTask对象,保存到数据库中,调用flush()方法,进行INSERT操作,对象有ID。

然后我们在数据库中找到director,从他那里取出tasks字段,给他添加两个task。然后我们将导演保存到数据库中。之后,值 4 将出现在数据库中的 employee_id 列中的新任务 - 员工表中主管的 ID。

重要的!数据库中的表对于@ManyToOne@OneToMany注释是相同的。但是这些表的 Java 类是不同的。