06章 映射一对多双向关联关系、以及cascade、inverse属性
當類與類之間建立了關聯,就可以方便的從一個對象導航到另一個對象。或者通過集合導航到一組對象。例如:
對于給定的Emp對象,如果想獲得與它關聯的Dept對象,只要調用如下方法
Dept dept=emp.getDept(); //從Emp對象導航到關聯的Dept對象
以Dept(部門)類和Emp(員工)類為例:
一、配置雙向一對多關聯
需在Dept類中增加一個集合類型的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屬性對應的字段。因此不能用<property>元素來映射emps屬性,而要使用<set>元素:
<set name="emps"><key column="deptNo"></key> <!-- 多的一方 emp外鍵 --><one-to-many class="Emp" /></set>
解析:
<set>元素的name屬性:設定持久化類的屬性名。此處為Dept類的emps屬性。
<set>元素還包含兩個子元素:
①<key>元素:column屬性設定與所關聯的持久化類對應的表的外鍵
②<one-to-many>元素:class屬性設定與所關聯的持久化類
hibernate根據以上映射代碼獲得以下信息:
①<set>元素表明Dept類的emps屬性為java.util.Set集合類型
②<one-to-many>子元素表明emps集合中存放的是一組Emp對象
③<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"/><!-- 一對多一個配置,一個部門有N個員工 --><!--inverse="false" 主動方 維護關聯關系inverse="true" 不維護關聯關系(不干擾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"/><!-- 植入一個Dept對象 : 多對一--><many-to-one name="dept" class="Dept" column="deptNo"></many-to-one></class> </hibernate-mapping>
進而編寫測試類: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();}/** 一對多雙向關聯測試*/@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:當Session操縱當前對象時,忽略其他關聯的對象。它是cascade屬性的默認值.
?Save-update:當通過Session的save()、update()及saveOrUpdate()方法來保存或更新當前對象時,級聯保存所有關聯的新建的瞬時狀態的對象,并且級聯更新所有關聯的游離狀態的對象。
?Delete:當通過Session的delete()方法刪除當前對象時,會級聯刪除所有關聯的對象。
當通過Session的delete()方法刪除當前對象時,會級聯刪除所有關聯的對象。
?All:包含save-update,delete的行為。
解析:
級聯也就是說當我們保存持久化對象A的時候自動幫我們保存持久化對象B。
問題:cascade屬性寫在什么位置?
注:一對一或者多對一的時候,直接寫在標簽上,其他的寫在set標簽上。
如何實現添加部門的同時自動添加員工?
解析:可以使用cascade(級聯)方式
?
Test:雙向關聯 ?通過add()將新建的員工對象添加部門下
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(){//構建一個部門Dept dept=new Dept();dept.setDeptName("財務部");//構建一個員工Emp emp=new Emp();emp.setEmpName("張三");//指定員工隸屬的部門emp.setDept(dept);// setXXX 部門下的員工dept.getEmps().add(emp);//savesession.save(dept);session.save(emp);}}   三、<Set>元素下的inverse屬性(反轉)
inverse屬性指定了關聯關系中的方向。
inverse設置為false,則為主動方,由主動方負責維護關聯關系,默認是false 。
注意:inverse?決定是否把對對象中集合的改動反映到數據庫中,所以inverse只對集合起作用,也就是只對one-to-many或many-to-many有效(因為只有這兩種關聯關系包含集合,而one-to-one和many-to-one只含有關系對方的一個引用)。
代碼同理:
說明:如果我既給員工指定了自己所屬的部門,又將員工添加到部門集合中。那么這個時候reverse不設置,生成以下sql
inverse設置為true,不負責維護關聯關系
第二條insert語句已經在員工表中指定了自己所屬的部分,沒有必要再向數據庫發送一條update指令。
將inverse設置成true后,生成的語句如下圖所示。
?
轉載于:https://www.cnblogs.com/WuXuanKun/p/5832091.html
總結
以上是生活随笔為你收集整理的06章 映射一对多双向关联关系、以及cascade、inverse属性的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 【bzoj 1833】【codevs 1
- 下一篇: 爱之天神表情换洛瑶表情亏吗?
