一、基于主键的双向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>