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一对一关系映射详解