public class Dept {
private int deptId; private String deptName; // 【一對多】 部門對應的多個員工 private Set<Employee> emps = new HashSet<Employee>();
|
public class Employee {
private int empId; private String empName; private double salary; // 【多對一】員工與部門 private Dept dept;
Dept.hbm.xml |
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.b_one2Many">
<class name="Dept" table="t_dept"> <id name="deptId"> <generator class="native"></generator> </id> <property name="deptName" length="20"></property>
<!-- 一對多關聯映射配置 (通過部門管理到員工) Dept 映射關鍵點: 1. 指定 映射的集合屬性: "emps" 2. 集合屬性對應的集合表: "t_employee" 3. 集合表的外鍵字段 "t_employee. dept_id" 4. 集合元素的類型
--> <set name="emps"> <!-- table="t_employee" --> <key column="dept_id"></key> <one-to-many class="Employee"/> </set>
</class>
</hibernate-mapping>
|
|
Employee.hbm.xml |
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.b_one2Many">
<class name="Employee" table="t_employee"> <id name="empId"> <generator class="native"></generator> </id> <property name="empName" length="20"></property> <property name="salary" type="double"></property>
<!-- 多對一映射配置 Employee 映射關鍵點: 1. 映射的部門屬性 : dept 2. 映射的部門屬性,對應的外鍵字段: dept_id 3. 部門的類型 --> <many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>
</class>
</hibernate-mapping>
|
測試 |
public class App {
private static SessionFactory sf; static { sf = new Configuration() .configure() .addClass(Dept.class) .addClass(Employee.class) // 測試時候使用 .buildSessionFactory(); }
// 保存, 部門方 【一的一方法操作】 @Test public void save() {
Session session = sf.openSession(); session.beginTransaction();
// 部門對象 Dept dept = new Dept(); dept.setDeptName("應用開發部"); // 員工對象 Employee emp_zs = new Employee(); emp_zs.setEmpName("張三"); Employee emp_ls = new Employee(); emp_ls.setEmpName("李四"); // 關系 dept.getEmps().add(emp_zs); dept.getEmps().add(emp_ls);
// 保存 session.save(emp_zs); session.save(emp_ls); session.save(dept); // 保存部門,部門下所有的員工
session.getTransaction().commit(); session.close(); /* * 結果 * Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?) Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?) Hibernate: insert into t_dept (deptName) values (?) Hibernate: update t_employee set deptId=? where empId=? 維護員工引用的部門的id Hibernate: update t_employee set deptId=? where empId=? */ } // 【推薦】 保存, 部員方 【多的一方法操作】 @Test public void save2() {
Session session = sf.openSession(); session.beginTransaction();
// 部門對象 Dept dept = new Dept(); dept.setDeptName("綜合部"); // 員工對象 Employee emp_zs = new Employee(); emp_zs.setEmpName("張三"); Employee emp_ls = new Employee(); emp_ls.setEmpName("李四"); // 關系 emp_zs.setDept(dept); emp_ls.setDept(dept);
// 保存 session.save(dept); // 先保存一的方法 session.save(emp_zs); session.save(emp_ls);// 再保存多的一方,關系回自動維護(映射配置完)
session.getTransaction().commit(); session.close(); /* * 結果 * Hibernate: insert into t_dept (deptName) values (?) Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?) Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?) 少生成2條update sql */ }
}
|
總結:
在一對多與多對一的關聯關系中,保存數據最好的通過多的一方來維護關系,
這樣可以減少update語句的生成,從而提高hibernate的執行效率!
配置一對多與多對一,這種叫“雙向關聯”
只配置一對多, 叫“單項一對多”
只配置多對一, 叫“單項多對一”
注意:
配置了哪一方,哪一方才有維護關聯關系的權限!