而本篇的雙向關聯顧名思義就是雙方都認得對方,拿之前的資料為例子
一對多是宿舍(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 省略部份...
沒有留言:
張貼留言