Hibernate读书笔记-----Hibernate的关联映射之1-N关联映射(一)

2014-11-24 08:34:34 · 作者: · 浏览: 0

三、1—N
对于1-N而言,它的持久化类发生了一点改变,持久化类里需要使用集合属性。因为1的一端需要访问N的一端,而N的一端将以集合(Set)形式表现。
1、单向1-N关联
对于单向的1-N关联关系,只需要在1的一端增加Set类型的属性,该属性记录当前实体的关联实体。
同样以员工-部门为例(Employee-->Department)。两个持久化类如下:
Department
[java]
public class Department {
private Integer id;
private String name;
private Set employees; //关联关系

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Set getEmployees() {
return employees;
}

public void setEmployees(Set employees) {
this.employees = employees;
}

}

Employee
[java]
public class Employee {
private Integer id;
private String name;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}


1.1基于无连接表的单向1-N关联
对于1-N的单向关联,需要在1的一端增加对应的集合映射元素,如。在集合元素中需要增加子元素,该子元素用来映射外键。同时集合元素中需要使用元素来映射1-N关联关系。
下面是Department的映射文件Department.hbm.xml
[html]
















对于上面的映射文件,映射元素时并没有指定cascade属性,在默认的情况下,对主表实体的持久化操作不会级联到从表实体。
Employee.hbm.xml
[html]







使用下面代码来操作Department和Employee实体:保存一个Department实体和两个Employee实体
[java]
static void add(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();

Department department = new Department();
department.setName("国防部");

//建立两个对象
Employee employee1 = new Employee();
employee1.setName("chentmt1");

Employee employee2 = new Employee();
employee2.setName("chentmt2");

Set emps = new HashSet();
emps.add(employee1);
emps.add(employee2);

//设置Department和Employee之间的关联关系
department.setEmployees(emps);

session.save(department); //....1
session.save(employee2);
session.save(employee1);
tx.commit();
session.close();
}

分析上面代码段:
当程序运行到....1的时候,系统会持久化该对象:Department,而且这个对象已经关联了两个Employee对象。在这个时候Hibernate需要完成两件事:
1、执行insert语句想department表中插入一条记录
2、Hibernate试图执行update语句,将当前的department表记录关联的employee表记录的外键departmentID修改为该department记录的主键的值。
下面为上面代码段的sql语句:
[sql]
Hibernate: insert into department (departmentName) values ( )

Hibernate: insert into employee (employeeName) values ( )

Hibernate: insert into employee (employeeName) values ( )

Hibernate: update employee set departmentID= where employeeID=

Hibernate: update employee set departmentID= where employeeID=
从上面的sql语句中我们可以看到虽然程序仅仅需要为Department实体增加一个关联Employee实体,但是Hibernate会采用两条SQL语句来完成:一条inset语句插入一个条外键为null的employee记录,一条update语句修改插入的employee记录。造成这个问题的根本原因