天天看點

Hibernate,JPA 對象關系映射之關聯關系映射政策

關聯關系映射

關聯關系映射,是映射關系中比較複雜的一種映射關系,總的說來有一對一、一對多和多對多幾種關系。細分起來他們又有單向和雙向之分。下面我們逐一介紹一下。

單向 OneToOne

單向一對一是關聯關系映射中最簡單的一種,簡單地說就是可以從關聯的一方去查詢另一方,卻不能反向查詢。我們用下面的例子來舉例說明,清單 1 中的 Person 實體類和清單 2 中的 Address 類就是這種單向的一對一關系,我們可以查詢一個 Person 的對應的 Address 的内容,但是我們卻不能由一個 Address 的值去查詢這個值對應的 Person。

清單 1. 單向一對一關系的擁有端

@Entity 
 public class Person implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String name; 
    private int age; 
    @OneToOne 
 private Address address; 

 //   Getters & Setters 
 }      

清單 2. 單向一對一關系的反端

@Entity 
 public class Address implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String street; 
    private String city; 
 private String country; 
 // Gettes& Setters 
 }      

圖 1. 單向一對一關系對應的 ER 圖

Hibernate,JPA 對象關系映射之關聯關系映射政策

Figure 1. 單向一對一關系對應的 ER 圖

從圖 1 他們的 ER 圖上可以看出,這種單向的一對一關系在資料庫中是以外鍵的形式被映射的。其中關系的發出端存儲一個指向關系的接收端的一個外鍵。在這個例子中 Person 表中的 ADDRESS_ID 就是指向 address 标的一個外鍵,預設情況下這個外鍵的字段名稱,是以它指向的表的名稱加下劃線“_”加“ID”組成的。當然我們也可以根據我們的喜好來修改這個字段,修改的辦法就是使用 @JoinColumn 這個注解。在這個例子中我們可以将這個注解注釋在 Person 類中的 Address 屬性上去。

雙向 OneToOne

雙向關系有一方為關系的擁有端,另一方是關系的反端,也就是“Inverse”端。在這裡例子中 Person 擁有這個關系,而 Address 就是關系的“Inverse”端。Address 中我們定義了一個 person 屬性,在這個屬性上我們使用了 @OneToOne 注解并且定義了他的“mappedBy”屬性,這個在雙向關系的“Inverse”端是必需的,在下面将要介紹的雙向關系中也要用到這個屬性。

清單 3. 雙向一對一關系中的接受端

@Entity 
 public class Address implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String street; 
    private String city; 
 private String country; 
 @OneToOne(mappedBy = "address") 
 private Person person; 
 // Gettes& Setters 

 }      

單向 OneToMany

單向關系的一對多我們可以用清單 4 和清單 5 來說明。在關系的發出端 Person 中我們使用 OneToMany 這個注解對 cellPhones 這個屬性進行了注釋,cellPhones 中存儲的是 CellPhone 的一個 List 對象,JPA 就是用這種方式實作一對多的。

清單 4. 單向一對多關系的發出端

public class Person implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String name; 
    private int age; 
    @OneToMany 
    private List<CellPhone> cellPhones; 
    // Getters and Setters 
 }      

清單 5. 單向一對多關系的接收端

@Entity 
 public class CellPhone implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String manufacture; 
    private String color; 
    private Long  phoneNo; 
    // Getters and Setters 
 }      

圖 2. 單向一對多關系對應的 ER 圖

Hibernate,JPA 對象關系映射之關聯關系映射政策

Figure 2. 單向一對多關系對應的 ER 圖

在一對多關聯關系映射中,預設是以中間表的方式來映射這種關系的。如在本例中,中間表為 person_cellphone,表的名稱為關系的擁有端和 Inverse 端中間用下劃線連接配接。中間表的字兩個字段分别為兩張表的得表名加下劃線“_”加 ID 組成。當然我們也可以改表這種預設的中間表的映射方式,我們可以在關系的擁有端使用 @JoinClolum 來使用外鍵的方式映射這個關系。

雙向 OneToMany

清單 6. 雙向一對多關系的接受端

@Entity 
 public class Person implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String name; 
    private int age; 
  
    @OneToMany(mappedBy = "person") 
    private List<CellPhone> cellPhones; 
    // Getters and Setters 
 }      

清單 7. 雙向一對多關系的發出端

@Entity 
 public class CellPhone implements Serializable { 

    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    
    private String manufacture; 
    private String color; 
    private Long  phoneNo; 
    @ManyToOne 
    private Person person; 
    // Getters and Setters 
 }      

圖 3. 雙向一對多關系對應的 ER 圖

Hibernate,JPA 對象關系映射之關聯關系映射政策

Figure 3. 雙向一對多關系對應的 ER 圖

單向 ManyToMany

多對多關聯關系中隻能通過中間表的方式進行映射。本例的單向多對多關系如下所示。

在清單 8 中我們使用了 ManyToMany 這個注解來對 Teacher 中的 Students 進行注釋,其中 Teacher 就是關系的發出端。而在 Student 中我們并沒有作任何定義,這是單向多對多的所要求的。

清單 8. 單向多對多關系的發出端

@Entity 
 public class Teacher implements Serializable { 
   
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String name; 
    private Boolean gender; 
    private int age; 
    private int height; 
    @ManyToMany 
 private List<Student> students; 
 // Getters  and  Setters 
 }      

清單 9. 單向多對多關系的反端

@Entity 
 public class Student implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String name; 
    private Boolean gender; 
    private int age; 
    private int height; 
   //Getters  and  Setters 
 }      

圖 4. Teacher 對應得資料庫表

Hibernate,JPA 對象關系映射之關聯關系映射政策

Figure 4. Teacher 對應得資料庫表

圖 5. Students 對應得資料庫表

Hibernate,JPA 對象關系映射之關聯關系映射政策

Figure 5. Students 對應得資料庫表

圖 6. 中間生成表

Hibernate,JPA 對象關系映射之關聯關系映射政策

Figure 6. 中間生成表

雙向 ManyToMany

清單 10. 雙向多對多關系的擁有端

@Entity 
 public class Teacher implements Serializable { 
   
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String name; 
    private Boolean gender; 
    private int age; 
    private int height; 
    @ManyToMany 
 private List<Student> students; 
 // Getters  and  Setters 
 }      

清單 11. 雙向多對多關系的反端

@Entity 
 public class Student implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String name; 
    private Boolean gender; 
    private int age; 
    private int height; 
    @ManyToMany(mappedBy = "students") 
    private List<Teacher> teachers; 
    //Getters  and  Setters 
 }      

圖 7. 雙向多對多關系對應的 ER 圖

Hibernate,JPA 對象關系映射之關聯關系映射政策

Figure 7. 雙向多對多關系對應的 ER 圖

總結