天天看點

Hibernate之 繼承映射

Hibernate的繼承映射可分為四種:

1、普通的繼承映射

需求:現在有動物(Animal這個類) 還有Dog這個類 和 Cat這個類 要求使用繼承映射來完成這個關聯關系的配置

Animal.java

public class Animal {
    //private int aid;
    private String color;
    private String name;
    /*public int getAid() {
        return aid;
    }
    public void setAid(int aid) {
        this.aid = aid;
    }*/
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
           

Cat.java

public class Cat extends Animal{
    private int cId;
    private String tail;
    public int getcId() {
        return cId;
    }
    public void setcId(int cId) {
        this.cId = cId;
    }
    public String getTail() {
        return tail;
    }
    public void setTail(String tail) {
        this.tail = tail;
    }
}
           

Dog.java

public class Dog extends Animal{
    private int dId;
    private String foot;

    public String getFoot() {
        return foot;
    }

    public void setFoot(String foot) {
        this.foot = foot;
    }

    public int getdId() {
        return dId;
    }

    public void setdId(int dId) {
        this.dId = dId;
    }


}
           

映射檔案:Cat.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">

 <!--package是否可以省略?
            可以
            省略之後類的名字 編寫全路徑就OK了       
 -->       
 <hibernate-mapping  package="com.wc.entity"  default-lazy="false"> 
    <!--一個class就相當于對應了一張表
         name:表示的是我們對應資料庫表的那個對象的名字  這個名字如果上面沒有配置package的話那麼是需要全路徑的
         table:這個标簽是我們的JAVA對象  在資料庫表中對應的這個表名
         abstract:這個用在繼承映射的時候 這個類是否在資料庫對應表的問題
         lazy:是否這個對象支援懶惰形加載 (我們隻有在使用這個資料的時候那麼 才加載這個資料  如果我們不需要使用這個資料的話 那麼就不會加載)
         abstract="true" lazy="true"
         table:是否可以省略?
                        可以的
                        省略之後預設的表明就是實體的名字
    -->

    <class name="Cat" table="a_cat">
       <!--配置的主鍵
          id:是用來配置這個主鍵的(每一個表都有主鍵) 值直接寫我們實體裡面的主鍵屬性 
          column:這個是用來定義這個列的列名的
          type:表示的是目前的這個類中的屬性的資料格式是什麼  這裡可以寫java裡面的類型的全路徑 也可以寫hibernate中支援的資料類型
          column:可以省略 預設的字段就是屬性的名字  
          type:也可以省略:預設的類型和實體的資料類型是一樣的
        -->
        <id name="cId">
            <generator class="native"></generator>
        </id>
        <!--配置的是普通的列
            property:設定的是普通的列  
            column:列名(目前對象的屬性在資料庫中對應的列名)  可以省略
            lazy:是否支援懶惰性的加載  :也預設值
            not-null:是否可以為null
            unique:是否這個列的值是唯一的
            type:可以省略 預設資料類型和實體中的屬性的類型一直
            length:設定的是長度(有點必須的)


        -->
        <property name="color"></property>
        <property name="name"></property>
        <property name="tail"></property>
    </class>
</hibernate-mapping>
           

2、所有子類存在一張表

Animal.java與Cat.java同上

映射檔案:Animal.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">

 <!--package是否可以省略?
            可以
            省略之後類的名字 編寫全路徑就OK了       
 -->       
 <hibernate-mapping  package="com.wc.entity"  default-lazy="false"> 
    <!--一個class就相當于對應了一張表
         name:表示的是我們對應資料庫表的那個對象的名字  這個名字如果上面沒有配置package的話那麼是需要全路徑的
         table:這個标簽是我們的JAVA對象  在資料庫表中對應的這個表名
         abstract:這個用在繼承映射的時候 這個類是否在資料庫對應表的問題
         lazy:是否這個對象支援懶惰形加載 (我們隻有在使用這個資料的時候那麼 才加載這個資料  如果我們不需要使用這個資料的話 那麼就不會加載)
         abstract="true" lazy="true"
         table:是否可以省略?
                        可以的
                        省略之後預設的表明就是實體的名字
    -->

    <class name="Animal" table="a_animal">
       <!--配置的主鍵
          id:是用來配置這個主鍵的(每一個表都有主鍵) 值直接寫我們實體裡面的主鍵屬性 
          column:這個是用來定義這個列的列名的
          type:表示的是目前的這個類中的屬性的資料格式是什麼  這裡可以寫java裡面的類型的全路徑 也可以寫hibernate中支援的資料類型
          column:可以省略 預設的字段就是屬性的名字  
          type:也可以省略:預設的類型和實體的資料類型是一樣的
        -->
        <id name="id">
            <generator class="native"></generator>
        </id>
        <!--配置的是普通的列
            property:設定的是普通的列  
            column:列名(目前對象的屬性在資料庫中對應的列名)  可以省略
            lazy:是否支援懶惰性的加載  :也預設值
            not-null:是否可以為null
            unique:是否這個列的值是唯一的
            type:可以省略 預設資料類型和實體中的屬性的類型一直
            length:設定的是長度(有點必須的)
        -->
         <!--整個分類
                               下面這個就是分類的這個列
        -->
        <discriminator  column="a_type" type="string" length="20"></discriminator>
         <!--配置的是普通的列-->
        <property name="color"></property>
        <property name="name"></property>
        <!--分别來配置我們的子類-->
        <subclass name="Cat" discriminator-value="a_cat">
            <property name="tail" type="string"></property>
        </subclass> 
            <subclass name="Dog" discriminator-value="a_dog">
            <property name="foot" type="string"></property>
        </subclass> 
    </class>
</hibernate-mapping>
           

3、所有類都對應一張表

java檔案同上

映射檔案:Animal.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">

 <!--package是否可以省略?
            可以
            省略之後類的名字 編寫全路徑就OK了       
 -->       
 <hibernate-mapping  package="com.wc.entity"  default-lazy="false"> 
    <!--一個class就相當于對應了一張表
         name:表示的是我們對應資料庫表的那個對象的名字  這個名字如果上面沒有配置package的話那麼是需要全路徑的
         table:這個标簽是我們的JAVA對象  在資料庫表中對應的這個表名
         abstract:這個用在繼承映射的時候 這個類是否在資料庫對應表的問題
         lazy:是否這個對象支援懶惰形加載 (我們隻有在使用這個資料的時候那麼 才加載這個資料  如果我們不需要使用這個資料的話 那麼就不會加載)
         abstract="true" lazy="true"
         table:是否可以省略?
                        可以的
                        省略之後預設的表明就是實體的名字
    -->

    <class name="Animal" table="a_animal">
       <!--配置的主鍵
          id:是用來配置這個主鍵的(每一個表都有主鍵) 值直接寫我們實體裡面的主鍵屬性 
          column:這個是用來定義這個列的列名的
          type:表示的是目前的這個類中的屬性的資料格式是什麼  這裡可以寫java裡面的類型的全路徑 也可以寫hibernate中支援的資料類型
          column:可以省略 預設的字段就是屬性的名字  
          type:也可以省略:預設的類型和實體的資料類型是一樣的
        -->
        <id name="id">
            <generator class="native"></generator>
        </id>
        <!--配置的是普通的列
            property:設定的是普通的列  
            column:列名(目前對象的屬性在資料庫中對應的列名)  可以省略
            lazy:是否支援懶惰性的加載  :也預設值
            not-null:是否可以為null
            unique:是否這個列的值是唯一的
            type:可以省略 預設資料類型和實體中的屬性的類型一直
            length:設定的是長度(有點必須的)
        -->
         <!--整個分類
                               下面這個就是分類的這個列
        -->
         <!--配置的是普通的列-->
        <property name="color"></property>
        <property name="name"></property>
        <!--分别來配置我們的子類-->
        <joined-subclass name="Dog" table="d_dog">
            <key column="id"></key>
            <property name="foot"></property>
        </joined-subclass>
            <joined-subclass name="Cat" table="c_cat">
            <key column="id"></key>
            <property name="tail"></property>
        </joined-subclass>
    </class>
</hibernate-mapping>
           

4、子類按種類分表(父類沒有表):

java檔案同上

映射檔案:Animal.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">

 <!--package是否可以省略?
            可以
            省略之後類的名字 編寫全路徑就OK了       
 -->       
 <hibernate-mapping  package="com.wc.entity"  default-lazy="false"> 
    <!--一個class就相當于對應了一張表
         name:表示的是我們對應資料庫表的那個對象的名字  這個名字如果上面沒有配置package的話那麼是需要全路徑的
         table:這個标簽是我們的JAVA對象  在資料庫表中對應的這個表名
         abstract:這個用在繼承映射的時候 這個類是否在資料庫對應表的問題
         lazy:是否這個對象支援懶惰形加載 (我們隻有在使用這個資料的時候那麼 才加載這個資料  如果我們不需要使用這個資料的話 那麼就不會加載)
         abstract="true" lazy="true"
         table:是否可以省略?
                        可以的
                        省略之後預設的表明就是實體的名字
    -->

    <class name="Animal" abstract="true">
       <!--配置的主鍵
          id:是用來配置這個主鍵的(每一個表都有主鍵) 值直接寫我們實體裡面的主鍵屬性 
          column:這個是用來定義這個列的列名的
          type:表示的是目前的這個類中的屬性的資料格式是什麼  這裡可以寫java裡面的類型的全路徑 也可以寫hibernate中支援的資料類型
          column:可以省略 預設的字段就是屬性的名字  
          type:也可以省略:預設的類型和實體的資料類型是一樣的
        -->
        <id name="id">
            <generator class="assigned"></generator>
        </id>
        <!--配置的是普通的列
            property:設定的是普通的列  
            column:列名(目前對象的屬性在資料庫中對應的列名)  可以省略
            lazy:是否支援懶惰性的加載  :也預設值
            not-null:是否可以為null
            unique:是否這個列的值是唯一的
            type:可以省略 預設資料類型和實體中的屬性的類型一直
            length:設定的是長度(有點必須的)
        -->
         <!--整個分類
                               下面這個就是分類的這個列
        -->
         <!--配置的是普通的列-->
        <property name="color"></property>
        <property name="name"></property>
          <!--接下來就是配置加表的問題-->
        <union-subclass name="Dog" table="d_dog">
           <property name="foot"></property>
        </union-subclass>


       <union-subclass name="Cat" table="c_cat">
            <property name="tail"></property>
        </union-subclass>
    </class>
</hibernate-mapping>
           

注議事項:

第4中的id 要用手動輸入的方式,否則會報錯。

繼續閱讀