11.hibernate繼承映射

導(dǎo)讀:

  • 什么是繼承映射篙耗?
  • 繼承映射的分類
    • 所有類形成一張表
    • 每個類形成一張表
    • 只有子類生成表铃岔,父類不生成表
Paste_Image.png

什么是繼承映射

實體類之間互相有繼承關(guān)系,或者說多個實體類有公共部分叮喳,可以抽象出一個父類钝诚。這是對象之間的關(guān)系颖御,可是數(shù)據(jù)表存儲不一定是一個類對應(yīng)一張表,因此我們需要分類討論一下凝颇。

繼承映射的分類

上面已經(jīng)說過了潘拱,一共分成三種情況,其實對象之間的關(guān)系沒有變拧略,這三種情況都是表達了數(shù)據(jù)表的對應(yīng)關(guān)系芦岂。
在講具體每種情況前,先把各實體類代碼貼出來:

Animal.java

    package entity;
    
    public class Animal {
        private int id;
        private String name;
        private boolean sex;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public boolean isSex() {
            return sex;
        }
        public void setSex(boolean sex) {
            this.sex = sex;
        }
    }

Pig.java

    package entity;
    
    public class Pig extends Animal{
        private int weight;
    
        public int getWeight() {
            return weight;
        }
    
        public void setWeight(int weight) {
            this.weight = weight;
        }
        
        
    }

Dog.java

    package entity;
    
    public class Dog extends Animal{
        private int run;
    
        public int getRun() {
            return run;
        }
    
        public void setRun(int run) {
            this.run = run;
        }
        
    }

1.所有類形成一張表

Animal.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">
    <hibernate-mapping>
        <class name="entity.Animal" table="_animal">
            <id name="id">
                <generator class="native"/>
            </id>
            <!-- 下面就開始定義就是將pig和dog繼承進來垫蛆,都生成一張表 -->
            <!-- 下面的這個類型string是hibernate的禽最,不是java自己的String類型 --> 
            <!-- discriminator這個標(biāo)簽必須寫在所有屬性的第一個腺怯,要不然會報錯! -->
            <discriminator column="type" type="string" />
            <property name="name" />        
            <property name="sex" />
            <subclass name="entity.Pig" discriminator-value="P">
                <property name="weight"></property>
            </subclass>
            <subclass name="entity.Dog" discriminator-value="D">
                <property name="run"></property>
            </subclass> 
        </class>    
    </hibernate-mapping>

單元測試:

    package entity;
    
    import org.hibernate.classic.Session;
    
    import junit.framework.TestCase;
    import util.hibernateUtil;
    
    /**
     * 測試目的:
     * 這是繼承映射的第一種策略川无,多個類共同對應(yīng)一張表呛占。
     * 1. 用不同的子類去查詢數(shù)據(jù)
     * 2. 用父類多態(tài)的角度去查詢
     * 3. 根據(jù)不同的類查詢出來結(jié)果,因為涉及到延遲加載懦趋,看是否能判斷真實類類型
     * 
     * 結(jié)果:
     * 只要是查詢的時候不延時晾虑,那就能判斷實際的對象類型
     * @author arkulo
     *
     */
    
    public class TestDemo extends TestCase {
    //  初始化數(shù)據(jù)
        public void test1()
        {
            Session session = null;
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
                
                Dog dd = new Dog();
                dd.setName("叮當(dāng)");
                dd.setSex(false);
                dd.setRun(100);
                session.save(dd);
                
                Pig zz = new Pig();
                zz.setName("八戒");
                zz.setSex(false);
                zz.setWeight(60);
                session.save(zz);
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally{
                hibernateUtil.closeSession(session);
            }
        }
        
    //  用父類多態(tài)角度去查詢
        public void test2()
        {
            test1();
            System.out.println("----------------------------");
            Session session = null;
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
                
    //          load是延遲加載,所以用的是代理仅叫,因此不能判斷對象的類型是Dog
    //          如果必須判斷真實對象類型帜篇,那就該用get函數(shù),或者把class的lazy屬性設(shè)置成為false
    //          Animal an = (Animal)session.load(Animal.class, 1);
    //          if(an instanceof Dog)
    //          {
    //              System.out.println("我是小狗诫咱,我叫:"+an.getName());
    //          }else
    //          {
    //              System.out.println("我是小豬笙隙,我叫"+an.getName());
    //          }
                
                Dog dd = (Dog)session.get(Dog.class, 1);
                System.out.println(dd.getName());   
                
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally{
                hibernateUtil.closeSession(session);
            }
        }
        
    }

2.每個類形成一張表

Animal.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">
    <hibernate-mapping package="entity">
        <class name="entity.Animal" table="_animal">
            <id name="id">
                <generator class="native"/>
            </id>
            <property name="name" />        
            <property name="sex" />
            <!-- 下面就是各個實體類單獨程表的映射配置 -->
            <!-- pid是關(guān)聯(lián)animal表的主鍵,did同理 -->
            <joined-subclass name="Pig" table="_pig">
                <key column="pid"></key>
                <property name="weight"></property>
            </joined-subclass>  
            <joined-subclass name="Dog" table="_dog">
                <key column="did"></key>
                <property name="run"></property>
            </joined-subclass>
        </class>    
    </hibernate-mapping>

單元測試:

    package entity;
    
    import org.hibernate.classic.Session;
    
    import junit.framework.TestCase;
    import util.hibernateUtil;
    
    /**
     * 這個項目是多個關(guān)聯(lián)實體類坎缭,每個實體類映射成為一張表竟痰,但是只用一個hbm映射文件
     * 插入數(shù)據(jù)的時候,相當(dāng)于主附表
     * 
     * @author arkulo
     *
     */
    
    public class TestDemo extends TestCase {
    //  初始化數(shù)據(jù)
        public void test1()
        {
            Session session = null;
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
    //          產(chǎn)生兩天sql語句掏呼,一條插入Animal表凯亮,一條插入Dog表,did字段關(guān)聯(lián)animal表的主鍵
                Dog dd = new Dog();
                dd.setName("叮當(dāng)");
                dd.setSex(false);
                dd.setRun(100);
                session.save(dd);
    //          和上面同理哄尔,產(chǎn)生兩條SQL語句
                Pig zz = new Pig();
                zz.setName("八戒");
                zz.setSex(false);
                zz.setWeight(60);
                session.save(zz);
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally{
                hibernateUtil.closeSession(session);
            }
        }
        
    //  用父類多態(tài)角度去查詢
        public void test2()
        {
            test1();
            System.out.println("----------------------------");
            Session session = null;
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
                
    //          load是延遲加載,所以用的是代理柠并,因此不能判斷對象的類型是Dog
    //          如果必須判斷真實對象類型岭接,那就該用get函數(shù),或者把class的lazy屬性設(shè)置成為false
    //          sql語句是left out join臼予,一條SQL語句聯(lián)合查詢兩張表
    //          Animal an = (Animal)session.load(Animal.class, 1);
    //          if(an instanceof Dog)
    //          {
    //              System.out.println("我是小狗鸣戴,我叫:"+an.getName());
    //          }else
    //          {
    //              System.out.println("我是小豬,我叫"+an.getName());
    //          }
                
    //          采用inner join的方式粘拾,發(fā)出一條sql語句窄锅,關(guān)聯(lián)查詢animal和dog表
    //          Dog dd = (Dog)session.get(Dog.class, 1);
    //          System.out.println(dd.getName());   
                
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally{
                hibernateUtil.closeSession(session);
            }
        }
        
    }

3.只有子類生成表,父類不生成表

Animal.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">
    <hibernate-mapping package="entity">
        <!-- abstract設(shè)置為true缰雇,animal實體類就不會建表入偷,但不會影響到存儲和加載 -->
        <class name="entity.Animal" abstract="true">
            <id name="id">
                <!-- 這里不會生成表了,所以id就不能采用數(shù)據(jù)庫生成策略 -->
                <generator class="assigned"/>
            </id>
            <property name="name" />        
            <property name="sex" />
            <!-- 下面開始配置子類生成獨立的表 -->
            <union-subclass name="Pig" table="_pig">
                <property name="weight"></property>
            </union-subclass>
            <union-subclass name="Dog" table="_dog">
                <property name="run"></property>
            </union-subclass>
        </class>    
    </hibernate-mapping>

單元測試:

    package entity;
    
    import org.hibernate.classic.Session;
    
    import junit.framework.TestCase;
    import util.hibernateUtil;
    
    /**
     * 三個類械哟,每個具體類映射成一張表疏之,父類不映射成表
     * 
     * @author arkulo
     *
     */
    
    public class TestDemo extends TestCase {
    //  初始化數(shù)據(jù)
        public void test1()
        {
            Session session = null;
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
    //          這里要注意,id是由animal提供的暇咆,但是animal現(xiàn)在不會在去生成表了锋爪,因此
    //          這里的主鍵丙曙,我們只能自己指定,不能依靠數(shù)據(jù)庫生成其骄,當(dāng)然也可以使用uuid亏镰,那就需要設(shè)置id為String類型
                Dog dd = new Dog();
                dd.setId(1);
                dd.setName("叮當(dāng)");
                dd.setSex(false);
                dd.setRun(100);
                session.save(dd);
    //          和上面同理
                Pig zz = new Pig();
                zz.setId(2);
                zz.setName("八戒");
                zz.setSex(false);
                zz.setWeight(60);
                session.save(zz);
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally{
                hibernateUtil.closeSession(session);
            }
        }
        
    //  用父類多態(tài)角度去查詢
        public void test2()
        {
    //      這里如果用上面的函數(shù)來初始化數(shù)據(jù),記得重新指定id拯爽,因為是手動設(shè)定的
            test1();
            System.out.println("----------------------------");
            Session session = null;
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
                
    //          load是延遲加載索抓,所以用的是代理,因此不能判斷對象的類型是Dog
    //          如果必須判斷真實對象類型某抓,那就該用get函數(shù)纸兔,或者把class的lazy屬性設(shè)置成為false
    //          sql語句是left out join,一條SQL語句聯(lián)合查詢兩張表
                Animal an = (Animal)session.get(Animal.class, 1);
                if(an instanceof Dog)
                {
                    System.out.println("我是小狗否副,我叫:"+an.getName());
                }else
                {
                    System.out.println("我是小豬汉矿,我叫"+an.getName());
                }
                
    //          采用inner join的方式,發(fā)出一條sql語句备禀,關(guān)聯(lián)查詢animal和dog表
    //          Dog dd = (Dog)session.get(Dog.class, 1);
    //          System.out.println(dd.getName());   
                
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally{
                hibernateUtil.closeSession(session);
            }
        }
        
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洲拇,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子曲尸,更是在濱河造成了極大的恐慌赋续,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件另患,死亡現(xiàn)場離奇詭異纽乱,居然都是意外死亡,警方通過查閱死者的電腦和手機昆箕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門鸦列,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鹏倘,你說我怎么就攤上這事薯嗤。” “怎么了纤泵?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵骆姐,是天一觀的道長。 經(jīng)常有香客問我捏题,道長玻褪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任涉馅,我火速辦了婚禮归园,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘稚矿。我一直安慰自己庸诱,他們只是感情好捻浦,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著桥爽,像睡著了一般朱灿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钠四,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天盗扒,我揣著相機與錄音,去河邊找鬼缀去。 笑死侣灶,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缕碎。 我是一名探鬼主播褥影,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咏雌!你這毒婦竟也來了凡怎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤赊抖,失蹤者是張志新(化名)和其女友劉穎统倒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體氛雪,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡房匆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了报亩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坛缕。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖捆昏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情毙沾,我是刑警寧澤骗卜,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站左胞,受9級特大地震影響寇仓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜烤宙,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一遍烦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧躺枕,春花似錦服猪、人聲如沸供填。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽近她。三九已至,卻和暖如春膳帕,著一層夾襖步出監(jiān)牢的瞬間粘捎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工危彩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留攒磨,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓汤徽,卻偏偏與公主長得像娩缰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子泻骤,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法漆羔,類相關(guān)的語法,內(nèi)部類的語法狱掂,繼承相關(guān)的語法演痒,異常的語法,線程的語...
    子非魚_t_閱讀 31,644評論 18 399
  • 對象的狀態(tài) Hibernate中對象的狀態(tài) : 臨時/瞬時狀態(tài)趋惨、持久化狀態(tài)鸟顺、游離狀態(tài)臨時狀態(tài)特點:直接new出來的...
    奮斗的老王閱讀 925評論 0 49
  • 本文中我們介紹并比較兩種最流行的開源持久框架:iBATIS和Hibernate讯嫂,我們還會討論到Java Persi...
    大同若魚閱讀 4,312評論 4 27
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)兆沙,斷路器欧芽,智...
    卡卡羅2017閱讀 134,672評論 18 139
  • 我的記性一直很好,不是對于英語單詞記憶快或好葛圃,或是有著過目不忘的能力千扔,我一直記得我做過和經(jīng)歷過的一些事情,但是...
    卡綾閱讀 322評論 0 0