Hibernate 一对一映射(一)

  学习Hibernate的映射的过程中,觉得最重要的是从过程到对象思维的转换。只是去学那些配置如何来写,没有多大意思。如果真正去面对一个项目,从现实生活中抽象出实体,完成Hibernate的映射应该是一个很好地体验。说归说,那些基础的知识还是要整理总结。这篇博客主要总结一对一映射主键关联的单向和双向。

  Hibernate中一对一映射应该说是最简单的,也是最基础的。处理的是现实生活中的一对一这样的实体模型:比如一个人对应一个身份ID。

 Hibernate一对一映射实现的策略有两种:一种是主键关联;另一种是唯一外键关联。这两种策略的不同后面会介绍。

 Hibernate映射是有方向的,可能是单向也可能是双向,到底是哪种,需要由具体业务来确定。怎么来理解单向和双向呢?先看一张UML图:


 在这张图Person和IdCard的关系是单向的,Person可以看到IdCard,也就是查到了Person也就知道了IdCard了。反过来是不能的。


主键关联:原理是让两个实体的主键一致,这样不需要加入多余的字段。


单向:以上图为例


Person端:

package com.bjpowernode.hibernate;

public class Person {

	private int id;
	
	private String name;
	
	private 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;
	}

	public IdCard getIdCard() {
		return idCard;
	}

	public void setIdCard(IdCard idCard) {
		this.idCard = idCard;
	}
}
<?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>
	<class name="com.bjpowernode.hibernate.Person" table="t_person">
		<id name="id">
			<!-- 采用foreign生成策略,forgeign会取得关联对象的标识 -->
			<generator class="foreign">
				<!-- property只关联对象 -->
				<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>
IdCard端:

package com.bjpowernode.hibernate;

public class IdCard {
	
	private int id;
	
	private String cardNo;

	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;
	}
}
<?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>
	<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="cardNo"/>
	</class>
</hibernate-mapping>
映射出的表结构如下:



双向:UML图:



Person端没有变化:

IdCard端:

package com.bjpowernode.hibernate;

public class IdCard {
	
	private int id;
	
	private String cardNo;
	
	private 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;
	}

	public Person getPerson() {
		return person;
	}

	public void setPerson(Person person) {
		this.person = person;
	}
}
<?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>
	<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="cardNo"/>
		<one-to-one name="person"/>
	</class>
</hibernate-mapping>

  注意:文章中的例子都是Person端在维护一对一的关系,而且是通过Foreign主键生成策略得关联对象的标识(也可以理解为默认了casade属性),所以在save操作时,如果保存Person,它一定会先将IdCard也保存了,不会没有抛出TransientObjectException。如果保存的是IdCard,则不会保存Person,因为IdCard并不维护关系。


  总结:一对一主键关联:通过foreign策略让两个实体的主键一致,无需加入多余字段来维护。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值