Hibernate映射数据库关系

映射实体关联

您需要管理应用程序中这些持久性类之间的关系。
持久性类也称作“实体类”。
为此,Hibernate 允许您在映射文件中将实体类间的关系映射到各表间的关系。
Hibernate 允许您在Hibernate 映射文件中映射数据库表间的关系。
这些关系可以是以下某种类型:

一对一
一对多
多对多

一对一关联

您需要在Hibernate 映射文件中映射Java 类之间的一对一关联。
为此,您可以在Hibernate 映射文件中使用<many-to-one>元素。
此元素包含以下属性:
name指定用于关联类的属性名称。
class指定为name属性指定的属性提供值的相关类的完全限定名。
column指定外键列的名称,它存储name属性指定的属性的值。
cascade指定在一个表上执行的操作也会影响有类似更新的另一个表。
unique指定外键列包含唯一的值。此属性使得表之间的链接为一对一关联。
not-null指定如果设置为true,外键列就不能包含null 值。

<hibernate-mapping>
<class name="Test.Person" table="PERSON">
    <id name="personID" type="string"><column name="PERSONID" length="10" />
        <generator class="assigned" />
    </id>
    <property name="personName" type="string"><column name="PERSONNAME" length="40" />
    </property>
    <many-to-one name="personDetail" class="Test.PersonInfo" column="personDetailID" not-null="true" cascade="all" unique="true" />
</class> 
</hibernate-mapping>

表示使用元素在PERSON 表和PERSONINFO 表之间映射一对一关联。该元素的unique属性指定在PERSON 表中为PERSONINFO 表中PERSONDETAILID 列的每个值存在唯一的值。

一对多关联:

您可以使用Hibernate 映射文件中的<one-to-many>元素将类与包含一对多关系的数据库中的表映射起来,如以下代码段所示:

<hibernate-mapping>
<class name="Test.Authors" table="AUTHORS">
    ......
    <set cascade="all" name="BOOKS">
        <key column="authorid"/>
        <one-to-many class="Test.Books"/> 
    </set>
</class>

<class name="Test.Books" table="Books">
    ......
</class>
</hibernate-mapping>

<one-to-many>元素用于将Authors和Books类分别映射到AUTHORS 表和BOOKS 表。

多对多关联:

您可以使用Hibernate 映射文件中的<many-to-many>元素将类与包含多对多关系的数据库中的表映射起来,如以下代码段所示:

<hibernate-mapping>
<class name="Test.Student" table="STUDENT">
    ......
    <set cascade="all" name="courses" table="REGISTRATION">
        <key column="STUDENTID"/>
        <many-to-many class="Test.Course" column="COURSEID"/>
    </set>
</class>
</hibernate-mapping>

<many-to-many>元素用于映射Student类和Course类之间的关联。



映射类继承

通过继承关系使Java 类相互关联。
然而,继承关系不能在数据库的各表间实现。
因此,您需要在映射类和数据库表时,在Hibernate 映射文件中显式映射类的继承关系。
Hibernate 提供以下映射类型来支持继承层次结构:

每个具体类一张表:

在每个具体类一张表映射中,在继承层次结构中为每个类创建一张表
每张表为类的所有属性(包括继承属性)定义了列。
在创建了表和类之后,您需要在Hibernate 映射文件中映射它们。
您可以使用<union-subclass>元素在映射文件中映射子类。
这个元素包含以下常用属性:
name指定子类的名称。
table指定将与子类映射的表的名称

例如:

<hibernate-mapping>
<class name="Test.Books" table="BOOKS">
    ......
    <union-subclass name="Test.SEBooks" table="SEBOOKS">
        <property name="specialFeatures" type="string">
            <column length="200" name="SPECIALFEATURES"/>
        </property> 
    </union-subclass>
    <union-subclass name="Test.INBooks" table="INBOOKS">
        <property name="bookLanguage" type="string">
            <column length="20" name="BOOKLANGUAGE"/>
        </property> 
    </union-subclass> 
</class>
</hibernate-mapping> 

<class>元素提供了超类Book的映射信息。
<union-subclass>元素用于将每个子类与数据库中相应的表映射。
上述代码中,<class>元素提供了父类Book的映射信息。<union-subclass>元素继承父类的属性。
因此,它不映射已由<class>元素映射的属性

实现每个具体类一张表映射策略具有以下缺点:
对于在超类中映射的每个属性而言,所有子类表中的列名必须是相同的。
每张表为类的所有属性(包括继承属性)定义了列。这就造成了值的重复。
需要单独的查询来从存储具体类的数据的每个表检索数据。
超类属性中的更改会造成子类表的各个列的更改。

每个类一张表:

在每个类层次结构一张表映射策略中,在继承层次结构中为所有类创建一张表
这就不会造成为类层次结构中的每个类创建的表中有重复的列名。
然而,您需要在区分子类的对象的表中创建额外的列。
此列称作“鉴别器”。
存储在此列中的值用于识别子类所表示的行。

以下元素用于实现每个类层次结构一张表映射:
<discriminator>:借助以下属性指定鉴别器列的设置:
column指定鉴别器列的名称
type指定存储在鉴别器列中的值的数据类型

<subclass>:借助以下属性指定子类的设置:
name指定子类的名称。
discriminator-value指定用于当前子类的鉴别器值。

例如:

<hibernate-mapping>
<class name="Test.Books" table="BOOKDETAILS">
    ......
    <discriminator column="BOOKTYPE" type= "string"/>
    ......
    <subclass name="Test.SEBooks" discriminator-value="SE"> ...... </subclass>
    <subclass name="Test.INBooks" discriminator-value="IN"> ...... </subclass>
</class>
</hibernate-mapping>

每个类层次结构一张表简化了映射,而且您无需用重复的列名创建多个表。
然而,如果继承层次结构增加了,而且包含多个类,表的大小就增加了。
此外,在为继承层次结构中的所有类创建单个表时,类中不常见的列包含null 值。
因此,如果类层次结构增加,存储在表中的null 值的数量也会增加。这会影响数据库的数据完整性。

每个子类一张表:


这里写图片描述


在每个子类一张表映射策略中,为每个类创建单个表
然而,不会为存储子类的对象的表中的继承属性重复列。
存储超类的对象的表包含主键,它用作存储子类对象的表中的外键。
要实现每个子类一张表映射,您需要使用Hibernate 映射文件中的<joined-subclass>元素。
例如:


<hibernate-mapping>
<class name="Test.Books" table="BOOKS">
    ......
    <property name="bookTitle" type="string">
        <column length="20" name="BOOKTITLE"/>
    </property>
    ......
    <joined-subclass name="Test.SEBooks" table="SEBOOKS">
            <key column="seBookID"/>
        <property name="specialFeatures" type="string">
            <column length="200" name="SPECIALFEATURES"/>
        </property>  
    </joined-subclass>
......
</class>
</hibernate-mapping>

<key>指定外键列的名称

<joined-subclass>映射Book类的子类

在每个子类一张表中,在表中使用外键关联来映射继承关系。
存储子类对象的表无需单独的查询
如果超类的属性更改了,您无需在存储子类对象的表的列中作出任何更改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值