Hibernate(12)_基于主键的双向1对1

一、基于主键的双向1对1
1.介绍:

  • 基于主键的映射策略:指一端的主键生成器使用 foreign 策略,表明根据”对方”的主键来生成自己的主键,自己并不能独立生成主键. <param> 子元素指定使用当前持久化类的哪个属性作为 “对方”

  • 采用foreign主键生成器策略的一端增加 one-to-one 元素映射关联属性,其one-to-one属性还应增加 constrained=“true” 属性;另一端增加one-to-one元素映射关联属性。

  • constrained(约束):指定为当前持久化类对应的数据库表的主键添加一个外键约束,引用被关联的对象(“对方”)所对应的数据库表主键

2.实体类
Department .java

public class Department {

    private Integer dId;
    private String dName;

    private Manager manager;
    //忽略getter和setter方法
    ...
}

Manager.java

public class Manager {

    private Integer mId;
    private String mName;

    private Department department;
    //忽略getter和setter方法
    ...
}

3.映射文件
Department.hbm.xml

<hibernate-mapping package="com.withXml.bothOneToOne.entity.withPrimaryKey" auto-import="false">
    <class name="Department" table="BOTH_DEPARTMENTS_PRIMARY">
        <id name="dId" type="java.lang.Integer" access="field">
            <column name="D_ID" />
            <!-- 使用外键的方式来生成当前主键 -->
            <generator class="foreign" >
                <!-- property属性指定使用哪一个持久化类的那个属性的主键作为外键 -->
                <param name="property">manager</param>
            </generator>
        </id>
        <property name="dName" type="java.lang.String" access="field">
            <column name="D_NAME" />
        </property>
        <!-- 
            基于主键的映射策略:指一端的主键生成器使用 foreign 策略,表明根据”对方”的主键来生成自己的主键,
            自己并不能独立生成主键. <param> 子元素指定使用当前持久化类的哪个属性作为 “对方”
            采用foreign主键生成器策略的一端增加 one-to-one 元素映射关联属性,其one-to-one属性还应
                        增加 constrained=“true” 属性;另一端增加one-to-one元素映射关联属性。
            constrained(约束):指定为当前持久化类对应的数据库表的主键添加一个外键约束,引用被关联的对象
        (“对方”)所对应的数据库表主键

         -->
        <one-to-one name="manager" class="Manager" constrained="true"></one-to-one>
    </class>
</hibernate-mapping>

Manager.hbm.xml

<hibernate-mapping package="com.withXml.bothOneToOne.entity.withPrimaryKey" auto-import="false">
    <class name="Manager" table="BOTH_MANAGERS_PRIMARY">
        <id name="mId" type="java.lang.Integer" access="field">
            <column name="M_ID" />
            <generator class="native" />
        </id>
        <property name="mName" type="java.lang.String" access="field">
            <column name="M_NAME" />
        </property>

        <one-to-one name="department" class="Department"></one-to-one>

    </class>
</hibernate-mapping>

4.CRUD测试

/**
* 保存操作
 */
@Test
public void testOneToOneSave(){
    //新建部门对象
    Department department = new Department();
    department.setdName("财务部");

    //新建管理者对象
    Manager manager = new Manager();
    manager.setmName("张铭");


    //设定关联关系
    department.setManager(manager);
    manager.setDepartment(department);

    //执行保存,先保存哪一个都可以
    session.save(manager);
    session.save(department);

}

/**
 * 查询操作
 */
@Test
public void testOneToOneGet(){
    //默认情况下,对关联属性使用懒加载,所以会出现懒加载异常
    Department department = (Department) session.get(Department.class, 1);
    System.out.println(department.getdName());

    //出现懒加载异常
//      session.close();
//      Manager managerName = department.getManager();
    //无异常,仅仅是显示对象的类型
//      System.out.println(managerName.getClass());
    //有异常,使用到了对象的属性
//      System.out.println(managerName.getmName());

    Manager managerName = department.getManager();
    System.out.println(managerName.getmName());
}

/**
 * 查询操作
 */
@Test
public void testOneToOneGet2(){
    //在查询没有外键的一端对象时,使用左外连接一并查出其关联的对象,并已经初始化
    Manager manager = (Manager) session.get(Manager.class, 1);
    System.out.println(manager.getmName());
}

5.总结
①实体类:双方各自添加对方实体类型的属性
②映射文件:在其中一方的映射文件中主键的生成策略使用foreign,同时指定使用哪个一个持久化类的那个属性的主键作为外键
详细如下:

<!-- 使用外键的方式来生成当前主键 -->
 <generator class="foreign" >
<!-- property属性指定使用哪一个持久化类的那个属性的主键作为外键 -->
    <param name="property">manager</param>
 </generator>

<!-- 
    基于主键的映射策略:指一端的主键生成器使用 foreign 策略,表明根据”对方”的主键来生成自己的主键,
    自己并不能独立生成主键. <param> 子元素指定使用当前持久化类的哪个属性作为 “对方”
    采用foreign主键生成器策略的一端增加 one-to-one 元素映射关联属性,其one-to-one属性还应
                   增加 constrained=“true” 属性;另一端增加one-to-one元素映射关联属性。
constrained(约束):指定为当前持久化类对应的数据库表的主键添加一个外键约束,引用被关联的对象
(“对方”)所对应的数据库表主键

    -->
   <one-to-one name="manager" class="Manager" 
        constrained="true">
   </one-to-one>

另一端

<one-to-onename="department" class="Department">
</one-to-one>
原文地址:https://www.cnblogs.com/tengpengfei/p/10453951.html