隨筆-124  評(píng)論-49  文章-56  trackbacks-0

          繼承映射的三種策略:
            * 單表繼承,每棵類繼承樹使用一個(gè)表
            * 具體表繼承,每個(gè)子類一個(gè)表
            * 類表繼承,每個(gè)具體類一個(gè)表
          -----------------------------------------------------------------
          每棵類繼承樹映射成一張表
          1、理解如何映射
            因?yàn)轭惱^承樹肯定是對(duì)應(yīng)多個(gè)類,要把多個(gè)類的信息存放在一張表中,必須有某種機(jī)制來區(qū)分哪些記錄是屬于哪個(gè)類的。
           這種機(jī)制就是,在表中添加一個(gè)字段,用這個(gè)字段的值來進(jìn)行區(qū)分。用hibernate實(shí)現(xiàn)這種策略的時(shí)候,有如下步驟:
           父類用普通的<class>標(biāo)簽定義
           在父類中定義一個(gè)discriminator,即指定這個(gè)區(qū)分的字段的名稱和類型
           如:<discriminator column=”XXX” type=”string”/>
           子類使用<subclass>標(biāo)簽定義,在定義subclass的時(shí)候,需要注意如下幾點(diǎn):
           Subclass標(biāo)簽的name屬性是子類的全路徑名
           在Subclass標(biāo)簽中,用discriminator-value屬性來標(biāo)明本子類的discriminator字段(用來區(qū)分不同類的字段)
           的值Subclass標(biāo)簽,既可以被class標(biāo)簽所包含(這種包含關(guān)系正是表明了類之間的繼承關(guān)系),也可以與class標(biāo)
           簽平行。 當(dāng)subclass標(biāo)簽的定義與class標(biāo)簽平行的時(shí)候,需要在subclass標(biāo)簽中,添加extends屬性,里面的值
           是父類的全路徑名稱。子類的其它屬性,像普通類一樣,定義在subclass標(biāo)簽的內(nèi)部。

          2、理解如何存儲(chǔ)
           存儲(chǔ)的時(shí)候hibernate會(huì)自動(dòng)將鑒別字段值插入到數(shù)據(jù)庫中,在加載數(shù)據(jù)的時(shí)候,hibernate能根據(jù)這個(gè)鑒別值
           正確的加載對(duì)象
           
          多態(tài)查詢:在hibernate加載數(shù)據(jù)的時(shí)候能鑒別出正真的類型(instanceOf)

            * get支持多態(tài)查詢
            * load只有在將<class>標(biāo)簽的lazy=false,才支持多態(tài)查詢
            * hql支持多態(tài)查詢 

          <!--
            Animal:                Bird extends Animal:   Pig extends Animal:
            private int id;         private int height;        private int weight;
            private String name;
          -->
            
          <class name="Animal" table="t_animal">
                  
          <id name="id">
                      
          <generator class="native"/>
                  
          </id>
                  
          <discriminator column="type" type="string"/><!--必須在id后面,是檢別器  -->
                  
          <property name="name"/>
                  //subclass表示子類,discriminator-value表示檢別字段的值
                  
          <subclass name="Pig" discriminator-value="P">
                      
          <property name="weight"/>
                  
          </subclass>
                  
          <subclass name="Bird" discriminator-value="B">
                      
          <property name="height"/>
                  
          </subclass>
              
          </class>

          public void testSave1(){
                  Session session
          =null;
                  
          try{
                      session
          =HibernateUtils.getSession();
                      session.beginTransaction();
                      
                      Pig pig
          =new Pig();
                      pig.setName(
          "豬八戒");
                      pig.setWeight(
          100);
                      session.save(pig);
                      
                      Bird bird
          =new Bird();
                      bird.setName(
          "鳥類");
                      bird.setHeight(
          50);
                      session.save(bird);
                      
                      session.getTransaction().commit();
                  }
          catch(Exception e){
                      e.printStackTrace();
                      session.getTransaction().rollback();
                  }
          finally{
                      HibernateUtils.closeSession(session);
                  }

              }


              
          public void testLoda1(){
                  Session session
          =null;
                  
          try{
                      session
          =HibernateUtils.getSession();
                      session.beginTransaction();
                      
                      Pig p
          =(Pig)session.load(Pig.class1);
                      System.out.println(p.getName());
                      
                      session.getTransaction().commit();
                  }
          catch(Exception e){
                      e.printStackTrace();
                      session.getTransaction().rollback();
                  }
          finally{
                      HibernateUtils.closeSession(session);
                  }

              }

              
              
          public void testLoda2(){
                  Session session
          =null;
                  
          try{
                      session
          =HibernateUtils.getSession();
                      session.beginTransaction();
                      
                      Animal a
          =(Animal)session.load(Animal.class1);
                      System.out.println(a.getName());
                      
                      session.getTransaction().commit();
                  }
          catch(Exception e){
                      e.printStackTrace();
                      session.getTransaction().rollback();
                  }
          finally{
                      HibernateUtils.closeSession(session);
                  }

              }

              
              
          public void testLoda3(){
                  Session session
          =null;
                  
          try{
                      session
          =HibernateUtils.getSession();
                      session.beginTransaction();
                      
                      Animal a
          =(Animal)session.load(Animal.class1);
                      
          //因?yàn)閘oad默認(rèn)支持lazy,我們看到的是Animal的代理對(duì)象
                      
          //所以通過instanceof是反應(yīng)不出正真的對(duì)象類型的
                      
          //因些load在默認(rèn)情況下是不支持多態(tài)查詢的
                      if(a instanceof Pig){
                          System.out.println(a.getName());
                      }
          else{
                          System.out.println(
          "不是");
                      }

                      
                      session.getTransaction().commit();
                  }
          catch(Exception e){
                      e.printStackTrace();
                      session.getTransaction().rollback();
                  }
          finally{
                      HibernateUtils.closeSession(session);
                  }

              }

          每個(gè)子類映射成一張表

          1、理解如何映射
            這種策略是使用joined-subclass標(biāo)簽來定義子類的。父類、子類,每個(gè)類都對(duì)應(yīng)一張數(shù)據(jù)庫表。
           在父類對(duì)應(yīng)的數(shù)據(jù)庫表中,實(shí)際上會(huì)存儲(chǔ)所有的記錄,包括父類和子類的記錄;在子類對(duì)應(yīng)的數(shù)據(jù)庫表中,
           這個(gè)表只定義了子類中所特有的屬性映射的字段。子類與父類,通過相同的主鍵值來關(guān)聯(lián)。實(shí)現(xiàn)這種策略的時(shí)候,
           有如下步驟:
           父類用普通的<class>標(biāo)簽定義即可
           父類不再需要定義discriminator字段
           子類用<joined-subclass>標(biāo)簽定義,在定義joined-subclass的時(shí)候,需要注意如下幾點(diǎn):
           Joined-subclass標(biāo)簽的name屬性是子類的全路徑名
           Joined-subclass標(biāo)簽需要包含一個(gè)key標(biāo)簽,這個(gè)標(biāo)簽指定了子類和父類之間是通過哪個(gè)字段來關(guān)聯(lián)的。
           如:<key column=”PARENT_KEY_ID”/>,這里的column,實(shí)際上就是父類的主鍵對(duì)應(yīng)的映射字段名稱。
           Joined-subclass標(biāo)簽,既可以被class標(biāo)簽所包含(這種包含關(guān)系正是表明了類之間的繼承關(guān)系),
           也可以與class標(biāo)簽平行。 當(dāng)Joined-subclass標(biāo)簽的定義與class標(biāo)簽平行的時(shí)候,需要在Joined-subclass
           標(biāo)簽中,添加extends屬性,里面的值是父類的全路徑名稱。子類的其它屬性,像普通類一樣,定義在joined-subclass標(biāo)簽的內(nèi)部。

          <!--
            Animal:                Bird extends Animal:   Pig extends Animal:
            private int id;         private int height;        private int weight;
            private String name;
          -->
            
          <class name="Animal" table="t_animal2">
                  
          <id name="id">
                      
          <generator class="native"/>
                  
          </id>
                  
          <property name="name"/>
                  
          <joined-subclass name="Pig" table="t_pag2">
                      
          <key column="pagid"/>
                      
          <property name="weight"/>
                  
          </joined-subclass>
                  
          <joined-subclass name="Bird" table="t_bird2">
                      
          <key column="birdid"/>
                      
          <property name="height"/>
                  
          </joined-subclass>
              
          </class>

          每個(gè)具體類映射成一張表

          1、理解如何映射
           這種策略是使用union-subclass標(biāo)簽來定義子類的。每個(gè)子類對(duì)應(yīng)一張表,而且這個(gè)表的信息是完備的,
           即包含了所有從父類繼承下來的屬性映射的字段(這就是它跟joined-subclass的不同之處,
           joined-subclass定義的子類的表,只包含子類特有屬性映射的字段)。實(shí)現(xiàn)這種策略的時(shí)候,有如下步驟:
           父類用普通<class>標(biāo)簽定義即可
           子類用<union-subclass>標(biāo)簽定義,在定義union-subclass的時(shí)候,需要注意如下幾點(diǎn):
           Union-subclass標(biāo)簽不再需要包含key標(biāo)簽(與joined-subclass不同)
           Union-subclass標(biāo)簽,既可以被class標(biāo)簽所包含(這種包含關(guān)系正是表明了類之間的繼承關(guān)系),
           也可以與class標(biāo)簽平行。 當(dāng)Union-subclass標(biāo)簽的定義與class標(biāo)簽平行的時(shí)候,需要在Union-subclass
           標(biāo)簽中,添加extends屬性,里面的值是父類的全路徑名稱。子類的其它屬性,像普通類一樣,
           定義在Union-subclass標(biāo)簽的內(nèi)部。這個(gè)時(shí)候,雖然在union-subclass里面定義的只有子類的屬性,
           但是因?yàn)樗^承了父類,所以,不需要定義其它的屬性,在映射到數(shù)據(jù)庫表的時(shí)候,依然包含了父類的所
           有屬性的映射字段。
           
          注意:在保存對(duì)象的時(shí)候id是不能重復(fù)的(不能使用自增生成主鍵)
             默認(rèn)父類的animal表會(huì)生成,設(shè)<class>的abstract="true"就不會(huì)生成 

          <!--
            Animal:                Bird extends Animal:   Pig extends Animal:
            private int id;         private int height;        private int weight;
            private String name;
          -->
            
          <class name="Animal" abstract="true">
                  
          <id name="id">
                      
          <generator class="assigned"/>
                  
          </id>
                  
          <property name="name"/>
                  
          <union-subclass name="Pig" table="t_pig3">
                      
          <property name="weight"/>
                  
          </union-subclass>
                  
          <union-subclass name="Bird" table="t_bird3">
                      
          <property name="height"/>
                  
          </union-subclass>
              
          </class>
          posted on 2009-11-03 16:15 junly 閱讀(188) 評(píng)論(0)  編輯  收藏 所屬分類: hibernate/orm
          主站蜘蛛池模板: 喜德县| 铅山县| 和硕县| 达州市| 渭源县| 岐山县| 竹山县| 基隆市| 平舆县| 隆化县| 永州市| 紫阳县| 青冈县| 兴国县| 陇南市| 宜兰市| 威宁| 义乌市| 屏山县| 莱州市| 惠水县| 新龙县| 喀喇| 西青区| 淮北市| 浦北县| 兰州市| 河南省| 漳平市| 娄烦县| 阳谷县| 泗水县| 海宁市| 平利县| 张家口市| 远安县| 大厂| 城市| 无棣县| 宁都县| 垫江县|