1. 程式人生 > >Hibernate級聯操作解密(inverse和cascade)

Hibernate級聯操作解密(inverse和cascade)

cls any con st2 hset 總結 map 例子 src

總結:

Cascade:對級聯操作進行限制,有如下幾個參數:

  all : 所有情況下均進行關聯操作。
  none:所有情況下均不進行關聯操作。這是默認值。
  save-update:在執行save/update/saveOrUpdate時進行關聯操作。
  delete:在執行delete時進行關聯操作。

Inverse:在一對多模型中,只能在一的一方設置,inverse的作用就是在級聯發生後,會再次更新子表數據的外鍵為主表的主鍵。確保子表外鍵不會為空。

下面演示一個班級學生的例子(一對多):

班級表javabean

public class Classes {

private Integer c_id;

private String c_name;

private String c_desc;

private Set<Student> student;

...}

班級表mapping

.....其他字段省略,只寫關聯部分的代碼

<set name="student" table="STUDENT" cascade="save-update" inverse="false" lazy="true">

<key>

<column name="C_ID" />//此處對應子表外鍵約束名

</key>

<one-to-many class="com.cky.model.Student" />

</set>

學生表bean如下

public class Student {

private Integer s_id;

private String s_name;

private Integer s_age;

private Classes cls;

....}

學生表mapping

...其他字段省略,只寫關聯部分的代碼

<many-to-one name="cls"

cascade="save-update" class="com.cky.model.Classes" fetch="join">

<column name="C_ID" />//自己的外鍵約束名

</many-to-one>

Classes Student是一對多關系,驗證inverse作用

1、classesdescade=”save-update” inverse=”false”或者不寫(默認false

執行如下操作:

Student st1=new Student("st1", 11);

Student st2=new Student("st2", 17);

Set<Student> stus=new HashSet<Student>();

stus.add(st1);

stus.add(st2);

//上面是創建兩個學生對象,並添加到stus集合中

//下面是創建classes對象,並將學生集合傳入

Classes cls=new Classes("班級1", "lal", stus);

ss.save(cls);

執行結果:註意最後的兩個更新操作

Hibernate: select max(C_ID) from CLASSES

Hibernate: select max(S_ID) from STUDENT

Hibernate: insert into CLASSES (C_NAME, C_DESC, C_ID) values (?, ?, ?)

Hibernate: insert into STUDENT (S_NAME, S_AGE, C_ID, S_ID) values (?, ?, ?, ?)

Hibernate: insert into STUDENT (S_NAME, S_AGE, C_ID, S_ID) values (?, ?, ?, ?)

Hibernate: update STUDENT set C_ID=? where S_ID=?

Hibernate: update STUDENT set C_ID=? where S_ID=?

技術分享

二、當classes descade=”save-update” inverse=”true”

執行結果:註意沒有update了

Hibernate: select max(C_ID) from CLASSES

Hibernate: select max(S_ID) from STUDENT

Hibernate: insert into CLASSES (C_NAME, C_DESC, C_ID) values (?, ?, ?)

Hibernate: insert into STUDENT (S_NAME, S_AGE, C_ID, S_ID) values (?, ?, ?, ?)

Hibernate: insert into STUDENT (S_NAME, S_AGE, C_ID, S_ID) values (?, ?, ?, ?)

技術分享

從結果可以看出來,當放棄維護關系的時候,少了兩個更新語句

Inverse:是否放棄維護關系,就是是否對子表外鍵的進行額外更新操作,保證子表外鍵是自己的主鍵。

當級聯發生時,有兩種情況:

1、如果inversefalse,即classes選擇維護關系的話。首先級聯添加時會把Student對象的值插入表,由於需要維護關系,所以他會再次更新這些數據的外鍵關系。

將外鍵更新成自己的主鍵,這樣他們一定有關系了。

2、如果inversetrue,即classes不維護關系,首先級聯添加時會把Student對象的值插入表,但不會再次更新這些數據的外鍵關系,如果數據沒有外鍵,就是空的,所以可以看到第二次執行中,由於我們創建Student對象時沒有指定classes,所以添加後表中的結果也是null

總結:inverse只能在一的一方設置,inverse的作用就是在級聯發生時,會再次更新子表數據的外鍵為主表的主鍵。確保子表外鍵不會為空。

正常情況都是將inverse設置成true來加快速度,子表數據的外鍵在創建子表對象時就設置好。

Hibernate級聯操作解密(inverse和cascade)