Hibernate 一对一关联关系

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate 一对一关联关系相关的知识,希望对你有一定的参考价值。

在Hibernate中,一对一关联关系有两种情况:

基于外键映射的一对一

基于主键映射的一对一


基于外键映射的一对一

     这种映射其实是由多对一而来,这种映射情况下,外键可以放在任意的一端,在需要存放外键的一端(简称a端),添加<many-to-one>节点,为<many-to-one>节点增加unique="true"属性来约束多对一成为一对一,另一端(简称b端)使用<one-to-one>节点来映射,并增加property-ref属性指定使用在该端(b端)被关联的另一端(a端)的非主键的字段作为关联字段,这句话比较拗口,下面结合例子来看看并理解

     举例模型为部门(Department)和经理(Manager)

package com.demo.one2one.foreign;

public class Department {

	private Integer id;
	private String deptName;
	private Manager mgr;

	get/set

}
package com.demo.one2one.foreign;

public class Manager {

	private Integer id;
	private String mgrName;
	private Department dept;

	get/set

}
<hibernate-mapping package="com.demo.one2one.foreign">
    <class name="Department" table="DEPARTMENT">
    
        <id name="id" type="java.lang.Integer">
            <column name="DEPT_ID" />
            <generator class="native" />
        </id>
        
        <property name="deptName" type="java.lang.String">
            <column name="DEPT_NAME" />
        </property>
        
        <!-- 使用many-to-one方式来映射1-1 -->
        <!-- unique:值为true时添加唯一约束,即该外键唯一而不可重复,这样就保证一对一映射 -->
        <many-to-one name="mgr" class="Manager" column="MRG_ID" unique="true"></many-to-one>
        
    </class>
</hibernate-mapping>
<hibernate-mapping package="com.demo.one2one.foreign">
    <class name="Manager" table="MANAGER">
    
        <id name="id" type="java.lang.Integer">
            <column name="MGR_ID" />
            <generator class="native" />
        </id>
        
        <property name="mgrName" type="java.lang.String">
            <column name="MGR_NAME" />
        </property>
        
        <!-- 在没有外键的一端使用one-to-one进行映射 -->
        <!-- property-ref属性指定被关联实体(Department)对应的数据表的主键以外的字段作为关联字段 -->
        <one-to-one name="dept" class="Department" property-ref="mgr"></one-to-one>
        
    </class>
</hibernate-mapping>

      简单的执行空测试,可以看到两个表,并且在department表中有外键mgr_id参照manager表的主键mgr_id,另外,在索引那一栏可以看到department表除了有一个主键的唯一索引,还有一个外键列的唯一索引,这就是在Department的配置文件中的<many-to-one>节点中加了unique="true"的作用

      下面来说一下为什么要加property-ref,看下面的例子(数据插入部分省略),这里先将property-ref属性删掉

	@Test
	public void testGet() throws Exception{
		Department department = (Department) session.get(Department.class, 1);
		System.out.println(department.getDeptName());
		System.out.println(department.getMgr().getMgrName());
	}

      下面是控制台打印结果

Hibernate: 
    select
        department0_.DEPT_ID as DEPT_ID1_0_0_,
        department0_.DEPT_NAME as DEPT_NAM2_0_0_,
        department0_.MRG_ID as MRG_ID3_0_0_ 
    from
        DEPARTMENT department0_ 
    where
        department0_.DEPT_ID=?
d-aa
Hibernate: 
    select
        manager0_.MGR_ID as MGR_ID1_1_1_,
        manager0_.MGR_NAME as MGR_NAME2_1_1_,
        department1_.DEPT_ID as DEPT_ID1_0_0_,
        department1_.DEPT_NAME as DEPT_NAM2_0_0_,
        department1_.MRG_ID as MRG_ID3_0_0_ 
    from
        MANAGER manager0_ 
    left outer join
        DEPARTMENT department1_ 
            on manager0_.MGR_ID=department1_.DEPT_ID 
    where
        manager0_.MGR_ID=?
m-aa

      乍一看结果并没有什么不对,但是在这里,sql语句出现了问题:我们可以看到Hibernate使用了表的左连接sql来查询数据,但是在限定条件出现了问题,应该是manager的mgr_id等于department的mgr_id而不是department的dept_id,这是因为在Manager的配置文件中不加property-ref时,左连接的条件默认为department的主键字段,这样显然是我们不想看到的,而加入property-ref="mgr"后,结果成了如下所示:

Hibernate: 
    select
        department0_.DEPT_ID as DEPT_ID1_0_0_,
        department0_.DEPT_NAME as DEPT_NAM2_0_0_,
        department0_.MRG_ID as MRG_ID3_0_0_ 
    from
        DEPARTMENT department0_ 
    where
        department0_.DEPT_ID=?
d-aa
Hibernate: 
    select
        manager0_.MGR_ID as MGR_ID1_1_1_,
        manager0_.MGR_NAME as MGR_NAME2_1_1_,
        department1_.DEPT_ID as DEPT_ID1_0_0_,
        department1_.DEPT_NAME as DEPT_NAM2_0_0_,
        department1_.MRG_ID as MRG_ID3_0_0_ 
    from
        MANAGER manager0_ 
    left outer join
        DEPARTMENT department1_ 
            on manager0_.MGR_ID=department1_.MRG_ID 
    where
        manager0_.MGR_ID=?
Hibernate: 
    select
        department0_.DEPT_ID as DEPT_ID1_0_0_,
        department0_.DEPT_NAME as DEPT_NAM2_0_0_,
        department0_.MRG_ID as MRG_ID3_0_0_ 
    from
        DEPARTMENT department0_ 
    where
        department0_.MRG_ID=?
m-aa

      如此便成了我们想要的左连接,其余测试与前文出入不大,可自行测试观察

本文出自 “11220092” 博客,请务必保留此出处http://11230092.blog.51cto.com/11220092/1753488

以上是关于Hibernate 一对一关联关系的主要内容,如果未能解决你的问题,请参考以下文章

hibernate学习---关联关系映射

关联映射级联操作关系维护 ---- Hibernate之一对多|多对一关系

Hibernate学习———— hibernate一对一关系映射详解

Hibernate关联关系映射之一对一关联关系

Hibernate,关系映射的多对一单向关联多对一双向关联一对一主键关联一对一外键关联多对多关系关联

hibernate映射的 关联关系:有 一对多关联关系,一对一关联关系,多对多关联关系,继承关系