外键一对一
通俗上讲就是在一张表中设置一个外键对应另一张表的主键
实现方法
-
对于基于外键的1-1关联,其外键可以存放在任意一边,在需要存放外键一端,增加many-to-one元素。为many-to-one元素增加unique=“true” 属性来表示为1-1关联
<many-to-one name="depNanamger" class="com.cfox.onetoone.Manager" unique="true"> <column name="MANAGER_ID"/> </many-to-one>
-
另一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段
<one-to-one name="magDep" class="com.cfox.onetoone.Department" property-ref="depNanamger"></one-to-one>
备注:
如果不使用property-ref 属性的 sql 在查询的时候使用的是两张表的主键,如下SQL 中manager0_.MAG_ID=department1_.DEP_ID
select
manager0_.MAG_ID as MAG_ID1_1_0_,
manager0_.MAG_NAME as MAG_NAME2_1_0_,
department1_.DEP_ID as DEP_ID1_0_1_,
department1_.DEP_NAME as DEP_NAME2_0_1_,
department1_.MANAGER_ID as MANAGER_3_0_1_
from
MANAGER manager0_
left outer join
DEPARTMENTS department1_
on manager0_.MAG_ID=department1_.DEP_ID
where
manager0_.MAG_ID=?
如果使用property-ref 属性的 sql 在查询的时候是使用设置的外键进行查询的,如下SQL 中manager0_.MAG_ID=department1_.MANAGER_ID
select
manager0_.MAG_ID as MAG_ID1_1_0_,
manager0_.MAG_NAME as MAG_NAME2_1_0_,
department1_.DEP_ID as DEP_ID1_0_1_,
department1_.DEP_NAME as DEP_NAME2_0_1_,
department1_.MANAGER_ID as MANAGER_3_0_1_
from
MANAGER manager0_
left outer join
DEPARTMENTS department1_
on manager0_.MAG_ID=department1_.MANAGER_ID
where
manager0_.MAG_ID=?
实现示例代码:
实体bean 和映射文件
public class Manager {
private Integer magId;
private String magName;
private Department magDep;
public Integer getMagId() {
//省略 get 和 set 方法
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-12-16 13:43:26 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.cfox.onetoone.Manager" table="MANAGER">
<id name="magId" type="java.lang.Integer">
<column name="MAG_ID" />
<generator class="native" />
</id>
<property name="magName" type="java.lang.String">
<column name="MAG_NAME" />
</property>
<!-- 映射 1-1 的关联关系: 在对应的数据表中已经有外键了, 当前持久化类使用 one-to-one 进行映射 -->
<!--
没有外键的一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段
-->
<one-to-one name="magDep" class="com.cfox.onetoone.Department" ></one-to-one>
</class>
</hibernate-mapping>
public class Department {
private Integer depId;
private String depName;
private Manager depNanamger;
// 省略 get 和 set 方法
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-12-16 13:43:26 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.cfox.onetoone.Department" table="DEPARTMENTS">
<id name="depId" type="java.lang.Integer">
<column name="DEP_ID" />
<generator class="native" />
</id>
<property name="depName" type="java.lang.String">
<column name="DEP_NAME" />
</property>
<!-- 使用 many-to-one 的方式来映射 1-1 关联关系 -->
<many-to-one name="depNanamger" class="com.cfox.onetoone.Manager" unique="true">
<column name="MANAGER_ID"/>
</many-to-one>
</class>
</hibernate-mapping>
使用注意
//在查询没有外键的实体对象时, 使用的左外连接查询, 一并查询出其关联的对象
//并已经进行初始化.
Manager mgr = (Manager) session.get(Manager.class, 1);
System.out.println(mgr.getMgrName());
System.out.println(mgr.getDept().getDeptName());
//1. 默认情况下对关联属性使用懒加载
Department dept = (Department) session.get(Department.class, 1);
System.out.println(dept.getDeptName());
//2. 所以会出现懒加载异常的问题.
// session.close();
// Manager mgr = dept.getMgr();
// System.out.println(mgr.getClass());
// System.out.println(mgr.getMgrName());
//3. 查询 Manager 对象的连接条件应该是 dept.manager_id = mgr.manager_id
//而不应该是 dept.dept_id = mgr.manager_id
Manager mgr = dept.getMgr();
System.out.println(mgr.getMgrName());
Department dep1 = new Department();
dep1.setDepName("Dep-AA");
Manager man1 = new Manager();
man1.setMagName("Man-AA");
dep1.setDepNanamger(man1);
man1.setMagDep(dep1);
//保存操作
//建议先保存没有外键列的那个对象. 这样会减少 UPDATE 语句
//如果先保存有外键的那个对象,没有外键的那个对象保存后要更新有外键的那个对象,来设置关联关系
/*
* session.save(dep1);
* session.save(man1);
* 执行的 SQL 语句
* Hibernate: insert into DEPARTMENTS (DEP_NAME, MANAGER_ID) values (?, ?)
* Hibernate: insert into MANAGER (MAG_NAME) values (?)
* Hibernate: update DEPARTMENTS set DEP_NAME=?, MANAGER_ID=? where DEP_ID=?
*/
session.save(dep1);
session.save(man1);
主键一对一
主键一对一就是两个表的主键进行一对一的映射关联
实现方法
-
基于主键的映射策略:指一端的主键生成器使用 foreign 策略,表明根据”对方”的主键来生成自己的主键,自己并不能独立生成主键. <param> 子元素指定使用当前持久化类的哪个属性作为 “对方”
<id name="magId" type="java.lang.Integer"> <column name="MAG_ID" /> <generator class="foreign" > <param name="property">magDep</param> </generator> </id>
-
采用foreign主键生成器策略的一端增加 one-to-one 元素映射关联属性,其one-to-one属性还应增加 constrained=“true” 属性;另一端增加one-to-one元素映射关联属性。
-
constrained(约束):指定为当前持久化类对应的数据库表的主键添加一个外键约束,引用被关联的对象(“对方”)所对应的数据库表主键
<one-to-one name="magDep" class="com.cfox.onetoone.in.Department" constrained="true"></one-to-one>
实现示例代码:
实体bean 和映射文件
public class Manager {
private Integer magId;
private String magName;
private Department magDep;
public Integer getMagId() {
//省略 get 和 set 方法
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-12-16 13:43:26 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.cfox.onetoone.Manager" table="MANAGER">
<id name="magId" type="java.lang.Integer">
<column name="MAG_ID" />
<generator class="native" />
</id>
<property name="magName" type="java.lang.String">
<column name="MAG_NAME" />
</property>
<!-- 映射 1-1 的关联关系: 在对应的数据表中已经有外键了, 当前持久化类使用 one-to-one 进行映射 -->
<!--
没有外键的一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段
-->
<one-to-one name="magDep" class="com.cfox.onetoone.Department" ></one-to-one>
</class>
</hibernate-mapping>
public class Department {
private Integer depId;
private String depName;
private Manager depNanamger;
// 省略 get 和 set 方法
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-12-16 13:43:26 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.cfox.onetoone.in.Department" table="DEPARTMENTS">
<id name="depId" type="java.lang.Integer">
<column name="DEP_ID" />
<generator class="native" />
</id>
<property name="depName" type="java.lang.String">
<column name="DEP_NAME" />
</property>
<one-to-one name="depNanamger" class="com.cfox.onetoone.in.Manager"></one-to-one>
</class>
</hibernate-mapping>
网友评论