“one-to-one(一对一映射)”对应的情景即两个实体之间的关系是一一对应,就像一个人只能有一个身份证号码一样。对应到“实体与表”之间的映射策略上来说,主要分为两种:

   (1)主键关联:即让两个对象具有相同的主键值,以表明他们之间的一一对应的关系;数据库表不会有额外的字段来维护他们之间的关系,仅通过表的主键来关联。

   (2)唯一外键关联:外键关联,本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以用来表示一对一关联关系。

    对象模型的映射原理,如图:

                   

java一对一映射是什么意思 一对一映射定义_hibernate

                  

java一对一映射是什么意思 一对一映射定义_主键_02


一对一主键关联映射:

  总而言之,一对一关联映射的原理即:让两个实体的主键一致,这样就不需要加入多余的字段了。

    拿上面的“Person”和“IdCard”举例说明,代码如下:

    IdCard实体类:

public class IdCard {
	private int id;
	private String name;
	
	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对应的配置文件:

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

         因为此时的一对一关联映射仍然是单向的,从Person指向IdCard,对于IdCard来说,无论是实体类,还是配置文件,正常写法。        

   Person实体类:

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;
	}
}

  Person类对应的配置文件:

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Person" table="t_person">
		<id name="id">
		<!-- 采用foreign生成策略,foreign会取得关联对象的标识 -->
			<generator class="foreign">
				<param name="property">idCard</param>
			</generator>
		</id>
		<property name="name"/>
		<!-- 表示当前主键,还是一个外键,参考了对端的主键(IdCard的主键),也就是生成外键约束语句 
			one-to-one指示hibernate如何加载其关联对象,默认根据主键加载,也就是拿到关系字段值,根据
			对端的主键来加载关联对象
		-->
		<one-to-one name="idCard" constrained="true"/>
	</class>
</hibernate-mapping>

        由于方向性,可知在实体类中需要加入对IdCard的引用,并生成get、set方法,同时在配置文件的<class>标签当中,主键标识采用foreign生成策略,<id>标签内侧套入<generator>标签的同时,<para>标签需要说明,foreign外键到底和谁相关?其实就是在实体中引入的idCard。

    最终加入<one-to-one>标签,指明name="idCard"且constrained="true".

    同时在一对一主键的添加和加载过程中,Person配置文件中使用“foreign”,使得测试代码不需要session.save(idCard)即可同时将IdCard和Person一同插入库中。可见,直接session.save(person),就能够把idCard插入到表中,这是foreign的特性。      

    双向一对一关联映射怎么做?

    有时候,一对一关联具有双向方向性,相对于单向,双向的改动量不是很大:

   (1)IdCard实体类加入对Peroson类的引用:

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

   (2)IdCard类的配置文件

<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的引用,同时在配置文件中加入<one-to-one>标签即可。

双向一对一唯一外键关联映射原理及具体映射

一对一唯一外键关联映射

原理:多对一映射,在外键地方加上唯一限制。采用<many-to-one>标签来映射,指定多的一端unique为true,这样就限制了多的一端的多重性为一,就是这样来映射的。

        

java一对一映射是什么意思 一对一映射定义_hibernate_03


如图,限制idCard的唯一性(unique),此时,Person类中id的class类型不再为foreign,设置为native即可。

双向一对一唯一外键关联映射原理及具体映射

   Person实体类:

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;
	}
}

        Person对应的配置文件:

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Person" table="t_person">
		<id name="id">
			<generator class="foreign">
				<param name="property">idCard</param>
			</generator>
		</id>
		<property name="name"/>
	</class>
</hibernate-mapping>

     IdCard实体类:

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

        IdCard对应的配置文件:

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Person" table="t_idCard">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<one-to-one name="person" property-ref="idCard"/>
	</class>
</hibernate-mapping>

    一对一唯一外键关联双向采用<one-to-one>标签映射,必须指定<one-to-one>标签中的property-ref属性为关键字段的名称。