程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Hibernate及JPA對象關系映射:關聯關系映射策略

Hibernate及JPA對象關系映射:關聯關系映射策略

編輯:關於JAVA

關聯關系映射

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

單向 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 圖

從圖 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 圖

在一對多關聯關系映射中,默認是以中間表的方式來映射這種關系的。如在本例中,中間表為 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 圖

單向 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 對應得數據庫表

圖 5. Students 對應得數據庫表

圖 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 圖

總結

關聯關系映射,是對象映射關系中相對復雜的一種,但也是用處最多的一種,因為數據中的表不可能都是單 獨存在,彼此之間必定存在千絲萬縷的聯系,這也是關系型數據庫的特征所在。同樣關聯關系的映射,也是對象關系映射中 的難點,重點,仔細揣摩,也還是很容易理解掌握的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved