首页 > 代码库 > 【SSH进阶之路】Hibernate映射——一对一双向关联映射(六)

【SSH进阶之路】Hibernate映射——一对一双向关联映射(六)

      上篇博文【SSH进阶之路】Hibernate映射——一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指仅仅能从人(Person)这端载入身份证端(IdCard),可是反过来。不能从身份证端载入人得信息。

如图所看到的:

      技术分享

      关键原因在于对象模型具有方向性:

单向:一端仅仅能载入还有一端。不能反过来。

双向:两端都能够载入还有一端。

      问题来了:怎样我们想从身份证端(IdCard)载入人(Person),怎么办呢?

      以下我们開始介绍一对一的双向关联映射。

 

 映射原理

 

       双向关联映射与单向关联映射的原理是一样的,双向关联映射并不影响存储。仅仅影响载入

所以,双向关联映射和单向关联映射的关系模型是一样的即数据库的表结构是一样的,仅仅是IdCard的实体类和配置文件(IdCard.hbm.xml)发生了一点点变化。

 

 对象模型

 

           技术分享

 

 从上图中能够看出:

        1、一个人仅仅有一张身份证,唯一的一个身份证号,对象之间是一对一的关系。

        2、两个对象得关系维护还是由person端决定(由于关系仅仅能由一端维护主键,否则关系就乱了)。

 

       依据上面的对象模型,我们能够看到Person端没有变化。可是要在IdCard端加上Person的引用,比如Person和IdCard实体类例如以下。

Person

package com.liang.hibernate;

public class Person {
	private int id;
	private String name;
	private IdCard idCard;
	
	public IdCard getIdCard() {
		return idCard;
	}
	public void setIdCard(IdCard idCard) {
		this.idCard = idCard;
	}
	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;
	}
}

 IdCard

package com.liang.hibernate;

public class IdCard {
	private int id;
	private String cardNo;
	private Person person;
	
	public Person getPerson() {
		return person;
	}
	public void setPerson(Person person) {
		this.person = person;
	}
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	public String getCardNo() {
		return cardNo;
	}
	public void setCardNo(String cardNo) {
		this.cardNo = cardNo;
	}
}

 

     不管是单向关联映射还是双向关联映射,他们都属于一对一关联映射,仅仅是他们主键的生成策略不同。分为主键关联映射和唯一外键关联映射。

     因为它们都属于一对一关联映射,所以,Hibernate封装双向关联映射时。主键关键映射和唯一外键关联映射的载入策略一样,都採用的是一对一<one-to-one name=""></one-to-one>,仅仅是属性设置不一致,所以,以下我们分开来看IdCard的配置文件。

 

分类:

 

主键关联映射

 

     同一对一单向关联映射类似,主键关联即利用主键进行关联。关联主键的值同样。以下我们看一下映射文件:

 

IdCard.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="com.liang.hibernate"> <class name="IdCard" table="t_idCard"> <id name="id"> <generator class="native"></generator> </id> <property name="cardNo"></property> <!-- 怎么载入对象,抓取策略:join联合查询(默认),select:一条条的查询 --> <one-to-one name="person" class="Person" fetch="join"></one-to-one> </class> </hibernate-mapping>

Person.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="com.liang.hibernate">
	<class name="Person" table="t_person">
		<id name="id">
		<!-- 採用foreign生成策略,forgeign会取得关联对象的标识 -->
			<generator class="foreign" >
				<param name="property">idCard</param>
			</generator>
		</id>
		<property name="name"></property>
		<!-- 
			one-to-one指示hibernate怎样载入其关联对象,默认依据主键载入
			也就是拿到关系字段值,依据对端的主键来载入关联对象
			
			constrained="true"表示,当前主键(person的主键)还是一个外键
			參照了对端的主键(IdCard的主键),也就是会生成外键约束语句
		 -->
		<one-to-one name="idCard" class="IdCard" constrained="true"></one-to-one>
	</class>
</hibernate-mapping>

生成的表结构

 技术分享

 

唯一外键关联映射

    

       一对一双向关联映射的外键关联映射也与一对一单向关联映射的外键关联映射类似,在其一对一的指向端(Person)存在一个唯一外键,该唯一外键与被指向端(IdCard)相关联,关联主键的值同样。以下我们看一下映射文件:
 

IdCard.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="com.liang.hibernate"> <class name="IdCard" table="t_idCard"> <id name="id"> <generator class="native"></generator> </id> <property name="cardNo"></property> <!-- 一对一唯一外键关联双向採用<one-to-one>标签来映射。必须指定<one-to-one> 标签中的property-ref属性为关系字段的名称 --> <one-to-one name="person" class="Person" property-ref="idCard"></one-to-one> </class> </hibernate-mapping>

Person.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="com.liang.hibernate"> <class name="Person" table="t_person"> <id name="id"> <generator class="native" ></generator> </id> <property name="name"></property> <!-- 因为它是一对一的唯一外键关联,它是多对一关联的特例,凝视能够直接写成多对一关联--> <!-- idCard属性,表达的是本对象与IdCard的多对一关系。 --> <many-to-one name="idCard" class="IdCard" column="idCardId" unique="true"></many-to-one> </class> </hibernate-mapping>

生成的表结构

        技术分享

 

对照

 

       一对一单向和双向关联映射的差别正是对象模型和关系模型的差别之中的一个。

对象模型:有方向性。它究竟是单向还是双向是由对象模型决定的即配置文件决定。

关系模型:没有方向性或者说是双向的。从不论什么一端都能够载入还有一端。

 

下载

 

         以上内容,仅仅证明了一对一双向关联映射不影响存储即没有改变表结构,但不能证明关联是双向的,须要写对应的測试用例,我们以源代码的形式给大家。源代码下载

 

 总结

 

       一对一双向关联映射并非必须的,是由需求下决定的。

假设没有这种需求。用户也没有要求。系统也不须要,就没有必要建立双向的关联映射。

 

 

      下篇博文。我们介绍多对多单向关联映射。谢谢关注。

 

【SSH进阶之路】Hibernate映射——一对一双向关联映射(六)