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

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

时间: 2024-12-23 14:24:45

Hibernate 一对一关联关系的相关文章

Hibernate一对一关联关系

一对一的关联关系有一下几类: 1. 单向一对一 a). 基于主键的 b). 基于外键的 2. 双向一对一 a). 基于外键的 好, 下面咱们主要说一下怎么来设置这种关系, 主要是说怎么用, 其中也说一下一些地方为什么这么配置. OneByOne 一: 基于主键的 单向一对一 我们使用 Person类和 IdCard类来做测试, 一个Person 只能对应一个 IdCard. Just So. Person类: package com.single.one2one_primary; public

hibernate 一对一关联关系 及其懒加载,总结

一对一,则有主对象和从对象之区别 若无主对象,则从对象亦无存在之意义. 主对象为person 从对象为idcard <hibernate-mapping package="cn.itcast.hibernate.domain"> <class name="Person"> <id name="id"> <generator class="native" /> </id>

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

人和身份证之间就是一个典型的一对一关联关系.实现一对一关联关系映射的方式有两种一种是基于外键,一种是基于主键,下面我们先看基于外键的关联方式 首先看他们的实体类 Person类 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package entity; public class Person {     private Integer id;     private String name;     pr

Hibernate映射一对一关联关系

映射一对一关联 Hibernate提供了两种映射一对一关联关系的方式,分别是按照外键映射和按照主键映射. 下面是员工表和档案信息表(员工和档案表之间的关系是一对一的关系)  档案表(dept) 1 public class Dept { 2 private Integer deptid; 3 private String mystreet; 4 private Emp emp; 5 6 public Dept() { 7 } 8 9 public Dept(Integer deptid, Str

Hibernate(5)—— 联合主键 、一对一关联关系映射(xml和注解) 和 领域驱动设计

俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: One to One 映射关系 一对一单向外键(XML/Annotation) 一对一双向外键关联(XML/Annotation) 联合主键 一对一单向外键联合主键(Xml/Annotation) 一对一组件关联(XML/Annotation) 理解组件 领域驱动设计——自动生成数据库脚本 一对一关系的小结 一些出错问题的总结 自动生成数据库脚本 一般在项目开发过程中,我们的习惯是先建好数据库和表,然后在进

Hibernate之关联关系映射(一对一主键映射和一对一外键映射)

1:Hibernate的关联关系映射的一对一外键映射: 1.1:第一首先引包,省略 1.2:第二创建实体类: 这里使用用户信息和身份证信息的关系,用户的主键编号既可以做身份证信息的主键又可以做身份证信息的外键,这里先做外键. 创建User.java: 用户和身份证一对一的关联关系映射       private IdCart idCart; IdCart.java: 身份证和用户,一对一的关系       private User user; 1 package com.bie.bean; 2

(十)Hibernate的一对一关联关系

一.概述 我们以Company与Address类为例,介绍映射一对一关联关系的方法. 一对一的关联方法有两种 -按照外键映射:两个表任意一个表定义一个外键,来关联另一个表. -按照主键映射:一个表的主键同时作为外键,和另一个表的主键保持一致. 二.按照外键映射 (1)创建实体类 public class Company { private Integer id; private String name; private Address address; public Integer getId(

Hibernate利用关联关系操纵对象

利用关联关系操纵对象 数据对象之间关联关系有一对一.一对多及多对多关联关系.在数据库操作中,数据对象之间的关联关系使用JDBC处理很困难.本节讲解如何在Hibernate中处理这些对象之间的关联关系.本节使用到4个类,它们分别是Student(学生).Card(学生证).Group(班级)和Course(课程),它们之间的关联关系如图1-1所示.这些实体存在级联(cascade)问题.例如,当删除一个班级的信息时,还要删除该班的所有学生的基本信息.如果直接使用JDBC执行这种级联操作,会非常烦琐

hibernate.一对一关联

实体类关系 一对一 一对多 多对一 多对多 Hibernate提供了两种映射一对一关联关系的方式:按照外键映射和按照主键映射.下面以员工账号和员工档案表为例,介绍这两种映射方式,并使用这两种映射方式分别完成以下持久化操作: (1)保存员工档案的同时分配给员工一个账号. (2)加载员工档案的同时加载账号信息. 1.按照外键映射 步骤一:创建实体类Users1和Resume1 Users1创建如下: public class Users1 { private Integer userid; priv