您的位置:首页 > 其它

Hibernate详解(3)——一对一映射分析

2012-05-28 09:37 435 查看
本节讲述一下Hibernate中一对一关系的配置和使用。一对一关系也是比较常见的一种关系,在Hibernate中可以分为单向一对一关系和双向一对一关系。分类的原因一般是由于需求决定的,单双向是站在不同的角度去看认为规定的。一对一关系相对来说比较少见。但是在某些时候也会用到。比如学生和学生证两个实体就是一对一的。


单向一对一

单向一对一是站在其中的一端看的,主要是根据需求决定的。单向标明一端持有另一端的引用,而另一端则没有引用。如下UML图:



这里面Student持有Card的引用,在加载Student的时候,Hibernate会自动加载上Card来。它们的hbm配置文件如下:

Student.hbm.xml.负责维护关系

[html] view
plaincopy

<?xmlversionxmlversion="1.0"?>

<!DOCTYPEhibernate-mapping PUBLIC

"-//Hibernate/HibernateMapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<classnameclassname="com.lsh.hibernate.Student" table="t_student">

<idnameidname="id">

<!--采用foreign生成策略,forgeign会取得关联对象的标识 -->

<generatorclassgeneratorclass="foreign">

<!--property只关联对象 -->

<paramnameparamname="property">card</param>

</generator>

</id>

<propertynamepropertyname="name"/>

<!--

one-to-one指示hibernate如何加载其关联对象,默认根据主键加载

也就是拿到关系字段值,根据对端的主键来加载关联对象

constrained="true表示,当前主键(person的主键)还是一个外键

参照了对端的主键(IdCard的主键),也就是会生成外键约束语句

-->

<one-to-onenameone-to-onename="idCard" constrained="true"/>

</class>

</hibernate-mapping>

Card.hbm.xml不负责维护主键,是一个简单的映射文件。

[html] view
plaincopy

<?xmlversionxmlversion="1.0"?>

<!DOCTYPEhibernate-mapping PUBLIC

"-//Hibernate/HibernateMapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<classnameclassname="com.lsh.hibernate.Card" table="t_card">

<idnameidname="id">

<generatorclassgeneratorclass="native"/>

</id>

<propertynamepropertyname="school"/>

</class>

</hibernate-mapping>


双向一对一

双向一对一是彼此都持有对方的引用,在一端加载的时候,另一端就会自动加载上来。看看双向一对一的UML图



配置文件如下

[html] view
plaincopy

Student.hbm.xml

<?xmlversionxmlversion="1.0"?>

<!DOCTYPEhibernate-mapping PUBLIC

"-//Hibernate/HibernateMapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="com.lsh.hibernate.Student" table="t_student">

<idnameidname="id">

<!--采用foreign生成策略,forgeign会取得关联对象的标识 -->

<generatorclassgeneratorclass="foreign">

<!--property只关联对象 -->

<param name="property">card</param>

</generator>

</id>

<propertynamepropertyname="name"/>

<!--

one-to-one指示hibernate如何加载其关联对象,默认根据主键加载

也就是拿到关系字段值,根据对端的主键来加载关联对象

constrained="true表示,当前主键(person的主键)还是一个外键

参照了对端的主键(IdCard的主键),也就是会生成外键约束语句

-->

<one-to-one name="card" constrained="true"/>

</class>

</hibernate-mapping>

它和上面的单向的Student.hbm.xml配置一样,这两个不同的是在Card.hbm.xml中使用<one-to-one>标签把它持有的student加载上来。

[html] view
plaincopy

<?xmlversionxmlversion="1.0"?>

<!DOCTYPEhibernate-mapping PUBLIC

"-//Hibernate/HibernateMapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="com.lsh.hibernate.Card" table="t_card">

<idnameidname="id">

<generatorclassgeneratorclass="native"/>

</id>

<property name="school"/>

<one-to-one name="student"/>

</class>

</hibernate-mapping>

上面的两种一对一都是采用主键关联的方式,即它们两个表的主键是一样的,student用的表是采用foreign的方式,引用Card的主键。一对一关联还有一种外键关联的方式。它的UML图和双向一对一一样,只是配置文件不一样。

首先看一下它们各自的配置文件。Student.hbml.xml和Card.hbm.xml

[html] view
plaincopy

<?xmlversionxmlversion="1.0"?>

<!DOCTYPEhibernate-mapping PUBLIC

"-//Hibernate/HibernateMapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<classnameclassname="com.lsh.hibernate.Student" table="t_student">

<idnameidname="id">

<generatorclassgeneratorclass="native"/>

</id>

<propertynamepropertyname="name"/>

<many-to-onenamemany-to-onename="card" unique="true"/>

</class>

</hibernate-mapping>

[html] view
plaincopy

<?xmlversionxmlversion="1.0"?>

<!DOCTYPEhibernate-mapping PUBLIC

"-//Hibernate/HibernateMapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<classnameclassname="com.bjpowernode.hibernate.Card" table="t_card">

<idnameidname="id">

<generatorclassgeneratorclass="native"/>

</id>

<propertynamepropertyname="school"/>

<one-to-onenameone-to-onename="student" property-ref="card"/>

</class>

</hibernate-mapping>

一对一外键关联,其实可以看做是一对多的一种特殊形式,多方退化成一。多方退化成一只需要在<many-to-one>标签中设置"unique"="true"。

这里面重要的一个知识点就是<many-to-one>和<one-to-one>的区别,这里主要应用了这个不同。<many-to-one>不仅可以加载到另一端的数据,还会在多的一端表中加入一个外键,而<one-to-one>只会加载另一端数据,不会影响表结构。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: