而本篇的雙向關聯顧名思義就是雙方都認得對方,拿之前的資料為例子
一對多是宿舍(Room)認得好幾位學生(Student)
多對一則是好幾個學生住在同一個房間
所以先來看看的雙向關聯中 Student 和 Room 類別的寫法
基本上 Student 的寫法跟"多對一"的 Student一樣,而 Room 的寫法則同 "一對多" 的 Room
程式如下:
Student (學生)
package MapPOJO;
public class Student implements java.io.Serializable
{
private Long id;
private String name;
private Room room; //Student 有 reference Room
public Student(){}
public Long getId(){
return id;
}
public void setId(Long id){
this.id = id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public Room getRoom(){
return room;
}
public void setRoom(Room room){
this.room = room;
}
}
房間(Room)
package MapPOJO;
package MapPOJO;
import java.util.Set;
public class Room implements java.io.Serializable
{
private Long id;
private String address;
private Set students; //如同一對多, 一個 Room 有好位學生
public Room(){}
public Long getId(){
return id;
}
public void setId(Long id){
this.id = id;
}
public String getAddress(){
return address;
}
public void setAddress(String address){
this.address = address;
}
public Set getStudents(){
return students;
}
public void setStudents(Set students){
this.students = students;
}
public void addStudents(Student student){
students.add(student);
}
public void removeStudents(Student student){
students.remove(student);
}
}
接下來再看看,組態檔的設定,基本上幾乎都不變只是有幾個地方須注意
首先先看看 Student.hbm.xml
再來看看 Room.hbm.xml
Hibernate 的雙向關聯裡
在一般的 Student 和 Room 物件之間的關連都是以 reference 達成
並且都是雙邊引用,固雙方都知道彼此存在
但資料庫中,彼此的繫結是靠外鍵來關聯,所以只要一個外來鍵即可
勢必有一方必須放棄維護它的引用關係
對於 inverse="true" 來說,就是告訴其中一方放棄維護外來鍵的權利
簡單說,資料庫只要一方維護外來鍵,另一方就透過 inverse 放棄
那由誰來維護? 通常都是由多的一方來維護(Student) (外鍵也在 student table)
所以在上述的 Room 的組態檔才會出現 inverse="true"
如果不加入 inverse="true" , 則 Room 就會去維護外來鍵
但由於外來鍵是在 student table 上
所以 Hibernate 會產生 Update SQL
接下來一樣用個 JSP 模擬存入一些資料
// JSP 省略部份...
%>
Student s1 = new Student(); //兩位學生對應到同一間房間
s1.setName("ZOO");
Student s2 = new Student();
s2.setName("XOO");
Room room = new Room();
room.setAddress("twoWay");
s1.setRoom(room);
s2.setRoom(room);
org.hibernate.SessionFactory sessionfactory = HibernateUtil.getSessionFactory();
org.hibernate.Session session1 = sessionfactory.openSession();
org.hibernate.Transaction tx = session1.beginTransaction();
session1.save(s1);
session1.save(s2);
//還記得 cascade 嗎,由於兩邊都有設定 cascade, 所以上述兩行也可改成 session1.save(room)
tx.commit();
session1.close();
%>
// JSP 省略部份...
沒有留言:
張貼留言