@一对一

All lectures for ZH purposes
第 1 级 , 课程 851
可用

5.1 一对一沟通的多种形式

两个 Entity 类之间的关系还有另一个有趣且相当具体的情况 - 一对一关系。

我称这种情况非常具体,因为它更多地是关于 Java 对象而不是数据库。在数据库中,表与表之间的关系只有两种选择:

  • 表行包含指向另一个表的 ID 的链接。
  • 服务表用于多对多关系。

在实体类的情况下,可能有几个注释描述的选项:

  • @嵌入式
  • 单边OneToOne
  • 双边一对一
  • @MapsId

下面我们将考虑其中最受欢迎的。

5.2 嵌入式

顺便说一下,我们已经考虑过最简单的一对一@Embedded通信选项——这是一个注解。在这种情况下,我们有两个类存储在数据库的同一个表中。

假设我们要将用户的地址存储在UserAddress类中:


@Embeddable
class UserAddress {
   @Column(name="user_address_country")
   public String country;
   @Column(name="user_address_city")
   public String city;
   @Column(name="user_address_street")
   public String street;
   @Column(name="user_address_home")
   public String home;
}

然后我们只需要在User类中添加一个具有此地址的字段:


@Entity
@Table(name="user")
class User {
   @Column(name="id")
   public Integer id;
 
   @Embedded
   public UserAddress address;
 
   @Column(name="created_date")
   public Date createdDate;
}

Hibernate 将完成剩下的工作:数据将存储在一个表中,但是在编写 HQL 查询时,您将需要对类字段进行操作。

HQL查询示例:

select from User where address.city = 'Paris'

5.3 单边OneToOne

想象一下现在的情况:我们有一个源表 employee 和一个引用 employee 的任务。但是我们可以肯定地知道最多可以将一项任务分配给一个用户。那么我们就可以用注解来描述这种情况了@OneToOne

例子:


@Entity
@Table(name="task")
class EmployeeTask {
   @Column(name="id")
   public Integer id;
 
   @Column(name="name")
   public String description;
 
   @OneToOne
   @JoinColumn(name = "employee_id")
   public Employee employee;
 
   @Column(name="deadline")
   public Date deadline;
}

Hibernate 将确保不仅一个任务有一个用户,而且一个用户只有一个任务。否则,这种情况实际上与@ManyToOne.

5.4 双边OneToOne

前面的选项可能有点不方便,因为通常您不仅要将员工分配给任务,还要将任务分配给员工。

为此,您可以将 EmployeeTask 字段添加到 Employee 类并为其提供正确的注释。


@Entity
@Table(name="employee")
class Employee {
   @Column(name="id")
   public Integer id;
 
   @OneToOne(cascade = CascadeType.ALL, mappedBy="employee")
   private EmployeeTask task;
}

重要的!employee 表没有task_id字段,而是使用task表的employee_id字段来建立表与表之间的关系。

在对象之间建立连接看起来像这样:


Employee director = session.find(Employee.class, 4);
EmployeeTask task = session.find(EmployeeTask.class, 101);
task.employee = director;
director.task = task;
 
session.update(task);
session.flush();

要删除链接,还必须从两个对象中删除链接:


Employee director = session.find(Employee.class, 4);
EmployeeTask task = director.task;
 
task.employee = null;
session.update(task);
 
director.task = null;
session.update(director);
 
session.flush();

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION