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的执行效率!
配置一对多与多对一,这种叫“双向关联”
只配置一对多, 叫“单项一对多”
只配置多对一, 叫“单项多对一”
注意:
配置了哪一方,哪一方才有维护关联关系的权限!