本篇博客將在上篇雙向一對多的情況下介紹inverse,cascade屬性的作用
inverse(反轉)
inverse:指定關聯關係的控制方向,默認由one方來維護。在關聯關係中,inverse="false"則爲主動方,由主動方負責維護關聯關係。在一對多關聯中,只能設置one方的inverse爲true,這將有助於性能的改善。
我先將我的Classes.hbm.xml代碼貼出來,(注意:在這裏我們配置的是雙向的一對多的配置方法,其他的配置請看我的上篇博客)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-8-13 10:41:54 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.yc.entity.Classes" table="CLASSES">
<id name="cid" type="int">
<column name="CID" />
<generator class="sequence" >
<param name="sequence">seq_classes_cid</param>
</generator>
</id>
<property name="cname" type="java.lang.String">
<column name="CNAME" />
</property>
<set name="students" table="STUDENT" inverse="false" lazy="true">
<key>
<column name="CID" />
</key>
<one-to-many class="com.yc.entity.Student" />
</set>
</class>
</hibernate-mapping>
便於之後的解說我將測試代碼也貼出來
package com.yc.test;
import java.util.Collections;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.yc.entity.Classes;
import com.yc.entity.Student;
import com.yc.utils.HibernateUtil;
//測試雙向一對多
public class MyTest3 {
@Test
//測試多對一
public void testSave(){
Classes c=new Classes("大唐官府");
Student s1=new Student("劍俠客");
Student s2=new Student("飛燕女");
//設置關聯關係
Collections.addAll(c.getStudents(), s1,s2);
s1.setCid(c);
s2.setCid(c);
Session session=HibernateUtil.getSession();
Transaction tx=session.beginTransaction();
session.save(c);
session.save(s1);
session.save(s2);
tx.commit();
HibernateUtil.closeSession(session);
}
}
OK,在這裏我們可以看見在hbm文件的set標籤中的inverse爲false,這會出現什麼問題呢?我們不妨運行一下測試代碼,來看看控制檯的信息
哇,我們發現了啥,對於已經填寫完成的學生信息,爲什麼會多出倆update的操作?
在這裏是因爲我們將inverse設置爲false,那麼他們的關聯關係就交給了one的一方去控制,所以我們在執行的時候還會執行倆條update的sql語句。
好了,到這裏,我們會發現,這倆條update語句沒作用啊,放在這裏礙眼不說還影響了性能,怎麼把它幹掉呢?我們來試試將inverse設置爲true。
<set name="students" table="STUDENT" inverse="true" lazy="true">
<!-- 指定關聯的外鍵列 -->
<key>
<column name="CID" />
</key>
<one-to-many class="com.yc.test3.Student3" />
</set>
再次執行我們的測試方法
yes,成功的執行並且解決掉了礙眼的update操作。
cascade(級聯)
cascade級聯屬性設置不爲none時,hibernate會自動持久化所關聯對象:all、save-update、delete、none細心的小夥伴會發現在測試方法中我已經將學生信息保存在班級信息中了,爲什麼還要再用session去save一下啊,這不重複了嗎?
OK,對於這個問題,發現的很好,就是我們的cascade屬性啦,同樣我們在hbm文件中加入我們的cascade屬性來測試一下
<set name="students" table="STUDENT" inverse="true" lazy="true" cascade="save-update">
<!-- 指定關聯的外鍵列 -->
<key>
<column name="CID" />
</key>
<one-to-many class="com.yc.entity.Student" />
</set>
再來修改我們的測試方法
@Test
public void testSave(){
Classes c=new Classes("大唐官府");
Student s1=new Student("劍俠客");
Student s2=new Student("飛燕女");
//設置關聯關係
Collections.addAll(c.getStudents(), s1,s2);
s1.setCid(c);
s2.setCid(c);
Session session=HibernateUtil.getSession();
Transaction tx=session.beginTransaction();
session.save(c); //級聯操作
//session.save(s1); //注意這倆行是註釋掉的
//session.save(s2);
tx.commit();
HibernateUtil.closeSession(session);
}
執行
JUnit通過,說明我們的cascade屬性起到了作用,級聯成功。當然如果你想通過保存學生來保存班級的信息,一個道理只需在student的hbm文件設置cascade即可。
在這裏我簡單的介紹一下cascade的四個屬性
1.save-update:在保存以及更新的時候進行級聯操作
2.delete:最刪除操作進行級聯操作
3.all:對所有的操作進行級聯操作
4.none:對所有的操作不進行級聯操作