06章 映射一对多双向关联关系、以及cascade、inverse属性
當(dāng)類與類之間建立了關(guān)聯(lián),就可以方便的從一個(gè)對(duì)象導(dǎo)航到另一個(gè)對(duì)象?;蛘咄ㄟ^集合導(dǎo)航到一組對(duì)象。例如:
對(duì)于給定的Emp對(duì)象,如果想獲得與它關(guān)聯(lián)的Dept對(duì)象,只要調(diào)用如下方法
Dept dept=emp.getDept(); //從Emp對(duì)象導(dǎo)航到關(guān)聯(lián)的Dept對(duì)象
以Dept(部門)類和Emp(員工)類為例:
一、配置雙向一對(duì)多關(guān)聯(lián)
需在Dept類中增加一個(gè)集合類型的emps屬性
private Set<Emp> emps=new HashSet<Emp>();public Set<Emp> getEmps() {return emps;
}public void setEmps(Set<Emp> emps) {this.emps = emps; 如何在映射文件中映射集合類型的emps屬性。由于在Dept表中沒有直接與emps屬性對(duì)應(yīng)的字段。因此不能用<property>元素來映射emps屬性,而要使用<set>元素:
<set name="emps"><key column="deptNo"></key> <!-- 多的一方 emp外鍵 --><one-to-many class="Emp" /></set>
解析:
<set>元素的name屬性:設(shè)定持久化類的屬性名。此處為Dept類的emps屬性。
<set>元素還包含兩個(gè)子元素:
①<key>元素:column屬性設(shè)定與所關(guān)聯(lián)的持久化類對(duì)應(yīng)的表的外鍵
②<one-to-many>元素:class屬性設(shè)定與所關(guān)聯(lián)的持久化類
hibernate根據(jù)以上映射代碼獲得以下信息:
①<set>元素表明Dept類的emps屬性為java.util.Set集合類型
②<one-to-many>子元素表明emps集合中存放的是一組Emp對(duì)象
③<key>子元素表明EMP表通過外鍵DEPTNO參照Dept表
Dept.hbm.xml代碼:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.happy.onetomanydouble"><class name="Dept" table="DEPT"><id name="deptNo"><generator class="sequence"><param name="sequence">SEQ_NUM</param></generator></id> <property name="deptName"/><!-- 一對(duì)多一個(gè)配置,一個(gè)部門有N個(gè)員工 --><!--inverse="false" 主動(dòng)方 維護(hù)關(guān)聯(lián)關(guān)系inverse="true" 不維護(hù)關(guān)聯(lián)關(guān)系(不干擾Emp的外鍵生成)--><set name="emps" cascade="save-update"><key column="deptNo"></key> <!-- 多的一方 emp外鍵 --><one-to-many class="Emp" /></set></class> </hibernate-mapping>
Emp.hbm.xml:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.happy.onetomanydouble"><class name="Emp" table="EMP"><id name="empId"><generator class="sequence"><param name="sequence">SEQ_NUM</param></generator></id> <property name="empName" type="string"/><!-- 植入一個(gè)Dept對(duì)象 : 多對(duì)一--><many-to-one name="dept" class="Dept" column="deptNo"></many-to-one></class> </hibernate-mapping>
進(jìn)而編寫測試類:Test 即可拿到deptNo為1的員工姓名
public class Test2 {Session session;Transaction tx; @Afterpublic void afterTest(){tx.commit();HibernateUtil.CloseSession();}@Beforepublic void initData(){session=HibernateUtil.getSession();tx=session.beginTransaction();}/** 一對(duì)多雙向關(guān)聯(lián)測試*/@Testpublic void oneToManyDoubleTest(){//獲取員工集合Dept dept=(Dept)session.load(Dept.class,1);Set<Emp> emps =dept.getEmps();for (Emp emp : emps) {System.out.println(emp.getEmpName());}} 二、cascade屬性
?none:當(dāng)Session操縱當(dāng)前對(duì)象時(shí),忽略其他關(guān)聯(lián)的對(duì)象。它是cascade屬性的默認(rèn)值.
?Save-update:當(dāng)通過Session的save()、update()及saveOrUpdate()方法來保存或更新當(dāng)前對(duì)象時(shí),級(jí)聯(lián)保存所有關(guān)聯(lián)的新建的瞬時(shí)狀態(tài)的對(duì)象,并且級(jí)聯(lián)更新所有關(guān)聯(lián)的游離狀態(tài)的對(duì)象。
?Delete:當(dāng)通過Session的delete()方法刪除當(dāng)前對(duì)象時(shí),會(huì)級(jí)聯(lián)刪除所有關(guān)聯(lián)的對(duì)象。
當(dāng)通過Session的delete()方法刪除當(dāng)前對(duì)象時(shí),會(huì)級(jí)聯(lián)刪除所有關(guān)聯(lián)的對(duì)象。
?All:包含save-update,delete的行為。
解析:
級(jí)聯(lián)也就是說當(dāng)我們保存持久化對(duì)象A的時(shí)候自動(dòng)幫我們保存持久化對(duì)象B。
問題:cascade屬性寫在什么位置?
注:一對(duì)一或者多對(duì)一的時(shí)候,直接寫在標(biāo)簽上,其他的寫在set標(biāo)簽上。
如何實(shí)現(xiàn)添加部門的同時(shí)自動(dòng)添加員工?
解析:可以使用cascade(級(jí)聯(lián))方式
?
Test:雙向關(guān)聯(lián) ?通過add()將新建的員工對(duì)象添加部門下
public class Test3 {Session session;Transaction tx; @Afterpublic void afterTest(){tx.commit();HibernateUtil.CloseSession();}@Beforepublic void initData(){session=HibernateUtil.getSession();tx=session.beginTransaction();}/**cascade*/@Testpublic void oneTest(){//構(gòu)建一個(gè)部門Dept dept=new Dept();dept.setDeptName("財(cái)務(wù)部");//構(gòu)建一個(gè)員工Emp emp=new Emp();emp.setEmpName("張三");//指定員工隸屬的部門emp.setDept(dept);// setXXX 部門下的員工dept.getEmps().add(emp);//savesession.save(dept);session.save(emp);}} 三、<Set>元素下的inverse屬性(反轉(zhuǎn))
inverse屬性指定了關(guān)聯(lián)關(guān)系中的方向。
inverse設(shè)置為false,則為主動(dòng)方,由主動(dòng)方負(fù)責(zé)維護(hù)關(guān)聯(lián)關(guān)系,默認(rèn)是false 。
注意:inverse?決定是否把對(duì)對(duì)象中集合的改動(dòng)反映到數(shù)據(jù)庫中,所以inverse只對(duì)集合起作用,也就是只對(duì)one-to-many或many-to-many有效(因?yàn)橹挥羞@兩種關(guān)聯(lián)關(guān)系包含集合,而one-to-one和many-to-one只含有關(guān)系對(duì)方的一個(gè)引用)。
代碼同理:
說明:如果我既給員工指定了自己所屬的部門,又將員工添加到部門集合中。那么這個(gè)時(shí)候reverse不設(shè)置,生成以下sql
inverse設(shè)置為true,不負(fù)責(zé)維護(hù)關(guān)聯(lián)關(guān)系
第二條insert語句已經(jīng)在員工表中指定了自己所屬的部分,沒有必要再向數(shù)據(jù)庫發(fā)送一條update指令。
將inverse設(shè)置成true后,生成的語句如下圖所示。
?
轉(zhuǎn)載于:https://www.cnblogs.com/WuXuanKun/p/5832091.html
總結(jié)
以上是生活随笔為你收集整理的06章 映射一对多双向关联关系、以及cascade、inverse属性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【bzoj 1833】【codevs 1
- 下一篇: 【BZOJ-30391057】玉蟾宫棋盘