SSH之hibernate—1:1的关联映射

     上篇博客写了1和n的关联映射,这里继续介绍1:1 的关联映射,看映射文件如何配置。

一、单向主键(persoon---->IdCard)

     主键一样,其中一边主键也是外键

1、对象模型

    每个person有唯一的IdCard,person维护关系,持有idCard的引用

2、实体模型 

  

   t_person的id既是主键也是外键,一个人有唯一的身份证号,从person中可以看到idCard,反过来不行

3、映射文件

IdCard:

<hibernate-mapping>
	<class name="com.zx.hibernate.IdCard" table="t_idCard">
		<id name="id">
			<generator class="native" />
		</id>
		<property name="cardNo" />
	</class>
</hibernate-mapping>

person:

<hibernate-mapping>
	<class name="com.zx.hibernate.Person" table="t_person">
		<id name="id">
		<!-- 采用foreign生成策略,会取得关联对象的标识 -->
			<generator class="foreign" >
				<!-- property只关联对象<span style="font-family:FangSong_GB2312;">,值是person持有引用</span>-->
				<param name="property">idcard</param>
			
			</generator>
		</id>
		<property name="name" />
		<!-- 
		    one-to-one标签指示hibernate如何加载其关联对象,默认根据主键加载
		    也就是拿到关系字段值,根据对端的主键加载关联对象
		
		     constrained="true" 表示当前主键(person中的主键)还是一个外键 
			参照对端的主键(IdCard的主键),生成外键约束语句
		-->
		<one-to-one name="idcard" constrained="true"/>
	</class>
</hibernate-mapping>
   生成的表在person中加了约束,person的id是外键参照对端的主键,但是person中不添加多余字段
二、双向主键(person----IdCard)      

      也就是从person可以看到idcard,从idcard可以看到person。对象模型和上面的相似,只是没有箭头。双方都持有对方的引用。映射文件中需要在idcard中加标签,即关联对象。如下:

<hibernate-mapping>
	<class name="com.zx.hibernate.IdCard" table="t_idCard">
		<id name="id">
			<generator class="native" />
		</id>
		<property name="cardNo" />
		<one-to-one name="person"  />
	</class>
</hibernate-mapping>

   这样就建立了双向关联,name是持有的引用的名字。<one-to-one>不影响存储,只影响加载,不会修改数据库,<many-to-one>会修改数据库。查询idcard也会自动加载person对象。


三、单向唯一外键

     就是平时设计数据库的外键,只是外键是唯一的。是多对一个特殊情况。对象模型和上面的相同,映射文件idcard没有变化,都是普通属性。person按照多对一的配置,只是要设置唯一性

<hibernate-mapping>
	<class name="com.zx.hibernate.Person" table="t_person">
		<id name="id">
			<generator class="native" >
				<param name="property">idcard</param>
			</generator>
		</id>
		<property name="name" />
		<many-to-one name="idcard" unique="true"/>
	</class>
</hibernate-mapping>
   
四、双向唯一外键

    对象模型变为双向,互相持有对方的引用,只是idcard查询的时候自动加载person。所以要加关系字段在idcard类和映射文件中。如下:

<hibernate-mapping>
	<class name="com.zx.hibernate.IdCard" table="t_idCard">
		<id name="id">
			<generator class="native" />
		</id>
		<property name="cardNo" />
		<one-to-one name="person" property-ref="idcard"/>
	</class>
</hibernate-mapping>
    一对一唯一外键关联双向采用<one-to-one>标签映射,必须指定标签中的属性:property-ref="idcard",这个属性为关系字段的名称。这个值必须和person中外键值一致,那样加载的时候会自动查找。


根据一段代码看看如何根据idcard查找person:

public void testoad2(){
		Session session = null;
		try{
			session = hibernateUtils.getSession();
			session.beginTransaction();
			
			IdCard idcard = (IdCard)session.load(IdCard.class,1 );
			System.out.println("cardNo=" + idcard.getCardNo());
			System.out.println("idcard.person.name=" + idcard.getPerson().getName());
			
			session.getTransaction().commit();
		}catch(Exception e){
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			hibernateUtils.closeSession(session);
		}
	}

      

五、总结

1、主键约束要求对象有相同的主键值,表名它们一一对应的关系,扩充性不好

2、一对一唯一外键关联就是多对一的特例,限制了唯一性,扩展性好,如果遇到1:1的建议使用这种方式

3、使用的比较多的是多对一,一对一相当少些


评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值