国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

精通Hibernate之映射繼承關(guān)系七(圖)

2019-11-18 12:57:14
字體:
供稿:網(wǎng)友

  Company與Employee類之間為一對多多態(tài)關(guān)聯(lián)關(guān)系,假如繼續(xù)關(guān)系樹的根類對應(yīng)一個表,或者每個類對應(yīng)一個表,那么就能映射Company類的employees集合。本節(jié)介紹如何映射多對一多態(tài)關(guān)聯(lián)。如圖14-11所示,ClassD與ClassA為多對一多態(tài)關(guān)聯(lián)關(guān)系。
  
 精通Hibernate之映射繼續(xù)關(guān)系七(圖)(圖一)

  
圖14-11 ClassD與ClassA為多對一多態(tài)關(guān)聯(lián)關(guān)系

  
  ClassA、ClassB和ClassC構(gòu)成了一棵繼續(xù)關(guān)系樹,假如繼續(xù)關(guān)系樹的根類對應(yīng)一個表,或者每個類對應(yīng)一個表,那么可以按以下方式映射ClassD的a屬性:
  
  <many-to-one name="a"
  class="ClassA"
  column="A_ID"
  cascade="save-update" />
  
  假定與ClassD對應(yīng)的表為TABLE_D,與ClassA對應(yīng)的表為TABLE_A,在TABLE_D中定義了外鍵A_ID,它參照TABLE_A表的主鍵。
  
  ClassD對象的a屬性既可以引用ClassB對象,也可以引用ClassC對象,例如:
  
  tx = session.beginTransaction();
  ClassD d=(ClassD)session.get("ClassD",id);
  ClassA a=d.getA();
  if(a instanceof ClassB)
  System.out.PRintln(((ClassB)a).getB1());
  if(a instanceof ClassC)
  System.out.println(((ClassC)a).getC1());
  tx.commit();
  
  以下代碼在映射ClassD類的a屬性時使用了延遲檢索策略:
  
  <many-to-one name="a"
  class="ClassA"
  column="A_ID"
  lazy="true"
  cascade="save-update" />
  
  當(dāng)Hibernate加載ClassD對象時,它的屬性a引用ClassA的代理類實例,在這種情況下,假如對ClassA的代理類實例進(jìn)行類型轉(zhuǎn)換,會拋出ClassCastException:
  
  ClassA a=d.getA();
  ClassB b=(ClassB)a; //拋出ClassCastException
  
  解決以上問題的一種辦法是使用Session.load()方法:
  
  ClassA a=d.getA();
  ClassB b=(ClassB)session.load(ClassB.class,a.getId());
  System.out.println(b.getB1());
  
  當(dāng)執(zhí)行Session的load()方法時,Hibernate并不會訪問數(shù)據(jù)庫,而是僅僅返回ClassB的代理類實例。這種解決辦法的前提條件是必須事先知道ClassD對象實際上和ClassA的哪個子類的對象關(guān)聯(lián)。
  
  解決以上問題的另一種辦法是顯式使用迫切左外連接檢索策略,避免Hibernate創(chuàng)建ClassA的代理類實例,而是直接創(chuàng)建ClassA的子類的實例:
  
  tx = session.beginTransaction();
  ClassD d=(ClassD)session.createCriteria(ClassD.class)
  .add(EXPression.eq("id",id))
  .setFetchMode("a",FetchMode.EAGER)
  .uniqueResult();
  ClassA a=d.getA();
  if(a instanceof ClassB)
  System.out.println(((ClassB)a).getB1());
  if(a instanceof ClassC)
  System.out.println(((ClassC)a).getC1());
  tx.commit();
  
  假如繼續(xù)關(guān)系樹的具體類對應(yīng)一個表,為了表達(dá)ClassD與ClassA的多態(tài)關(guān)聯(lián),需要在TABLE_D中定義兩個字段:A_ID和A_TYPE,A_TYPE字段表示子類的類型,A_ID參照在子類對應(yīng)的表中的主鍵。圖14-12顯示了表TABLE_D、TABLE_B和TABLE_C的結(jié)構(gòu)。
  
精通Hibernate之映射繼續(xù)關(guān)系七(圖)(圖二)

  
圖14-12 表TABLE_D、TABLE_B和TABLE_C的結(jié)構(gòu)


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 沙坪坝区| 吉水县| 峨边| 新平| 本溪市| 潼南县| 宁远县| 灯塔市| 古浪县| 莱西市| 台山市| 西峡县| 正定县| 项城市| 和田市| 江达县| 宁蒗| 保康县| 定南县| 香河县| 怀化市| 烟台市| 宁阳县| 阳高县| 沙洋县| 张家界市| 宁陕县| 伽师县| 东乌| 长白| 大渡口区| 连平县| 涡阳县| 龙江县| 耿马| 鹤壁市| 吐鲁番市| 萝北县| 潞城市| 景东| 甘洛县|