2010年9月4日 星期六

Hibernate 教學 - 雙向關聯

在前兩篇有介紹到 Hibernate 的"一對多"和"多對一"關聯

而本篇的雙向關聯顧名思義就是雙方都認得對方,拿之前的資料為例子

一對多是宿舍(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 省略部份...

沒有留言:

張貼留言