Hibernate級聯操作解密(inverse和cascade)
總結:
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"
<column name="C_ID" />//自己的外鍵約束名
</many-to-one>
Classes 和Student是一對多關系,驗證inverse作用
1、當classes的 descade=”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、如果inverse為false,即classes選擇維護關系的話。首先級聯添加時會把Student對象的值插入表,由於需要維護關系,所以他會再次更新這些數據的外鍵關系。
將外鍵更新成自己的主鍵,這樣他們一定有關系了。
2、如果inverse為true,即classes不維護關系,首先級聯添加時會把Student對象的值插入表,但不會再次更新這些數據的外鍵關系,如果數據沒有外鍵,就是空的,所以可以看到第二次執行中,由於我們創建Student對象時沒有指定classes,所以添加後表中的結果也是null。
總結:inverse只能在一的一方設置,inverse的作用就是在級聯發生時,會再次更新子表數據的外鍵為主表的主鍵。確保子表外鍵不會為空。
正常情況都是將inverse設置成true來加快速度,子表數據的外鍵在創建子表對象時就設置好。
Hibernate級聯操作解密(inverse和cascade)