Hibernate4-6 映射一对一关联关系

来源:互联网 发布:在线教育 java源码 编辑:程序博客网 时间:2024/06/08 11:16

  一对一关联关系的概述图如下所示:
这里写图片描述


1. 基于外键映射的1-1关联关系

  对于基于外键映射的1-1关联关系,其外键可以放在任意一端,但不能两边都使用外键映射。
  在需要存放外键的一端:增加many-to-one元素,并设置其unique属性为true来表示1-1关联,示例代码如下:

<!-- 配置多对一映射,并添加唯一性约束 --><many-to-one name="manager" class="Manager" column="MGR_ID" unique="true"></many-to-one>

  在不需存放外键的一端:增加one-to-one元素,且必须使用property-ref属性指定使用被关联实体主键以外的字段作为关联字段,示例代码如下:

<!-- 配置一对一映射 --><!-- 若不配置property-ref属性,则在左外连接查询时,将使用被关联实体的主键作为关联字段 --><one-to-one name="department" class="Department" property-ref="manager"></one-to-one>

  基于外键映射的1-1关联关系的数据库操作测试代码如下所示:

@Testpublic void testGet1() {    // 4. 在查询没有外键的实体对象时,使用左外连接一并查询其关联的对象,并进行初始化    Manager mgr = (Manager) session.get(Manager.class, 5);    System.out.println(mgr.getName());    System.out.println(mgr.getDepartment().getName());}@Testpublic void testGet() {    // 1. 默认情况下对关联属性使用懒加载,所以可能会出现懒加载异常的问题    Department dept = (Department) session.get(Department.class, 5);    System.out.println(dept.getName());    // 2. org.hibernate.LazyInitializationException//  session.close();//  System.out.println(dept.getManager().getName());    // 3. 查询Manager对象时左外连接条件有误,需在one-to-one中配置property-ref属性    System.out.println(dept.getManager().getName());}@Testpublic void testSave() {    Department dept = new Department();    dept.setName("DEPT-AA");    Manager mgr = new Manager();    mgr.setName("MGR-AA");    // 设置1-1关联关系    dept.setManager(mgr);     mgr.setDepartment(dept);    // 注意:建议先保存没有外键列的对象,以减少UPDATE语句    session.save(dept);    session.save(mgr);}

2. 基于主键映射的1-1关联关系

  主要策略:指一端的主键生成器使用foreign策略,即根据”对方”的主键来生成自己的主键,本身不能自动生成主键。
  在使用foreign主键生成器的一端:增加one-to-one元素,并设置其constrained属性为true,即当前持久化类对应数据库表的主键添加一个外键约束,示例代码如下:

<id name="id" column="MGR_ID" type="java.lang.Integer">    <!-- 使用外键的方式来生成当前主键 -->    <generator class="foreign">        <!-- property属性指定使用当前持久化类的哪一个属性的主键做外键 -->        <param name="property">department</param>    </generator></id><!-- 配置一对一映射:需要为其添加外键约束 --><one-to-one name="department" class="Department" constrained="true"></one-to-one>

  在不用foreign主键生成器的一端:增加one-to-one元素映射关联属性即可,示例代码如下:

<!-- 配置一对一映射 --><one-to-one name="manager" class="Manager"></one-to-one>

  基于主键映射的1-1关联关系的数据库操作测试代码如下所示:

package com.qiaobc.hibernate.one2one.primary;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;public class TestHibernate {    private SessionFactory sessionFactory; // 单实例的    private Session session; // 项目中不能声明为成员变量,可能会有并发问题    private Transaction transaction; // 项目中不能声明为成员变量,可能会有并发问题    @Before    public void init() {        // 创建Session对象并开启事务        Configuration configuration = new Configuration().configure();        ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()                .applySettings(configuration.getProperties())                .buildServiceRegistry();        sessionFactory = configuration.buildSessionFactory(serviceRegistry);        session = sessionFactory.openSession();        transaction = session.beginTransaction();    }    @Test    public void testGet1() {        // 4. 在查询有主键约束的实体对象时,使用左外连接一并查询其关联的对象,并进行初始化        Department dept = (Department) session.get(Department.class, 1);        System.out.println(dept.getName());        System.out.println(dept.getManager().getName());    }    @Test    public void testGet() {        // 1. 默认情况下对关联属性使用懒加载,所以可能会出现懒加载异常的问题        Manager mgr = (Manager) session.get(Manager.class, 1);        System.out.println(mgr.getName());        // 2. org.hibernate.LazyInitializationException//      session.close();//      System.out.println(dept.getManager().getName());        // 3. 查询Department对象时左外连接        System.out.println(mgr.getDepartment().getName());    }    @Test    public void testSave() {        Department dept = new Department();        dept.setName("DEPT-AA");        Manager mgr = new Manager();        mgr.setName("MGR-AA");        // 设置1-1关联关系        dept.setManager(mgr);         mgr.setDepartment(dept);        // 注意:无论先插入哪一个对象都不会有多余的UPDATE        session.save(dept);        session.save(mgr);    }    @After    public void destory() {        transaction.commit();        session.close();        sessionFactory.close();    }}
0 0
原创粉丝点击