@一對一

All lectures for TW 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