hibernate中的inverse的用法

 
inverse常用於一對多雙向關聯關係中。
以Student(學生)和Class(班級)爲例,它們之間的關係爲一對多的關係,即一個學生只能屬於一個班級,一個班級可以包含多個學

生。
學生類定義代碼:
Class Student{
  private int id;
  private String name;
  private Class class;
  //省略getter()和setter()方法
}
班級類定義代碼:
Class Class{
  private int id;
  private String name;
  private Set students = new HashSet();
  //省略getter()和setter()方法
}
Student類的映射文件:
<class name="Student" table="STUDENT">
   <id name="id" type="int" column="ID">
      <generator class="native" />  
   </id>
   <property name="name" type="string" column="NAME" />
   <many-to-one name="class" column="CLASS_ID" class="Class" cascade="save-update" /> 
</class>
Class類的映射文件:
<class name="Class" table="CLASS">
   <id name="id" type="int" column="ID">
     <generator class="native" />  
   </id>
   <property name="name" type="string" column="NAME" />
   <set name="students" table="STUDENT" cascade="save-update" inverse="false">
     <key column="CLASS_ID" />
     <one-to-many class="Student" />
   </set>
</class>
希望你能對這兩個映射文件所表達的數據庫模式有正確的認識。即STUDENT表中存在一個名爲CLASS_ID的字段,它和CLASS表中的ID字段是主外鍵關係。那個inverse屬性就是用來規定是由誰(Student或Class)來維護這個主外鍵關係的。
inverse的默認值爲false。
在處理邏輯代碼中,如下:
Class c1 = new Class();
c1.setName("一班");
Student s1 = new Student();
Student s2 = new Student();
s1.setName("Jason");
s2.setName("Tom");
c1.getStudents().add(s1);
c2.getStudents().add(s2);
s1.setClass(c1);
s2.setClass(c1);   //註釋1
session.save(c1);
上面的代碼會使Hibernate執行五條SQL語句,其中前三條是insert插入語句,後兩條是update更新語句。插入就不用說了,那麼爲什麼還要有更新語句呢?這是因爲Class類映射文件的<set>元素中指定了inverse="false",這就告之Hibernate:STUDENT表與CLASS表的主外鍵關係是由Class類來維護的。當執行save後,執行了三條insert語句,這三條語句中的後兩條是插入到STUDENT表的,它們的CLASS_ID字段是通過s1.getClass().getID()取出的,假如我將上面“註釋1”處修改爲s2.setClass(c2);(c2是另一個Class對象,可能是持久化對象),這樣,主外鍵關係不就亂了嗎。爲了保證主外鍵關係,Hibernate在這種情況下會再執行兩條update語句來更改STUDENT表中兩個新插入記錄的CLASS_ID字段,當然,這時CLASS_ID字段的取值是從c1對象中直接取得,而不再是s1.getClass().getID()方式了。
如果我們將Class類映射文件的<set>元素中的inverse屬性修改爲true,這就是告訴Hibernate:Class類不維護主外鍵關係了,這個任務就交給了Student類。於是,我們再執行上面的代碼,Hibernate就會只執行三條insert語句,而不會執行任何update語句。因爲Hibernate會通過Student類的s1.getClass().getID()和s2.getClass().getID()來確定CLASS_ID字段的值。
故,爲了節省數據庫資源,省卻不必要的update語句,我們一般建議在一對多雙向關聯關係中,將一方的inverse屬性設置爲true,即將主外鍵的關係交由多方來維護。
打個比方:在一個公司中,是老闆認識所有的員工容易,還是所有員工認識老闆容易?
我是一個Hibernate的初學者,前兩天剛剛研究了一下inverse屬性,有所心得。寫了這麼多東西,希望能對你有所幫助。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章