为了解决这个问题,程序必须在持久化Employee实体之前,让Employee实体能够知道它所关联的Department实体,也就是通过employee.setDepartment(department);方法建立关联关系,但是这个时候就已经变成了1-N的双向关联。所以,尽量少用1-N的单向关联,而改用1-N的双向关联。
1.2基于有连接表的单向1-N关联
对于有连接表的1-N关联映射,映射文件不再使用
所以Department.hbm.xml配置文件如下:
[html]
Employee.hbm.xml配置文件保持不变
如果我们依然通过使用操作方法:保存一个Department、两个Employee,这个时候,系统应该是产生5条sql语句。其中两条是用于向连接表中插入记录,从而建立Department和Employee之间的关联关系。
2、双向1-N关联
对于1-N关联,Hibernate推荐使用双向关联,而且不要让1端控制关联关系,而使用N的一端控制关联关系。
双向的1-N关联,两端都需要增加对关联属性的访问,N的一端增加引用到关联实体的属性,1的一端增加集合属性,集合元素为关联实体。
两个持久化类和上面差不多,只需要在Employee中增加对Department的引用属性即可。
2.1无连接表的双向1-N关联
对于无连接表的双向1-N关联。N的一端需要增加
在前面已经提到对于1-N关联映射,通常不提倡1的一端控制关联关系,而应该由N的一端来控制关联关系。此时我们可以再
Department映射文件:Department.hbm.xml
[html]
Employee映射文件:Employee.hbm.xml
[html] view plaincopyprint
下面的程序段用于保存一个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");
employee1.setDepartment(department); //建立两个对象的关联关系
Employee employee2 = new Employee();
employee2.setName("chentmt2");
employee2.setDepartment(department); //建立两个对象的关联关系
session.save(department); //....1
session.save(employee2);
session.save(employee1);
tx.commit();
session.close();
}
SQL语句:
[sql]
Hibernate: insert into department (departmentName) values ( )
Hibernate: insert into employee (employeeName, departmentID) values ( , )
Hibernate: insert into employee (employeeName, departmentID) values ( , )
通过上面的SQL语句可以看出,Hibernate并不是采用哪种先insert后update的方式来插入employee记录的。而是通过一条insert SQL语句来执行的。为什么?因为程序持久化Employee实体之前,Employee已经知道它所关联Department实体(employee2.setDepartment(department);)。 所以为了保证比较好的性能,需要注意以下两个问题:
1、应该先持久化主表对象:Department。因为我们希望程序在持久化从表:Employee对象时,Hibernate可以为他的外键属性值分配值。
2、先设置两个持久化类(Department和Employee)的关系,再保存持久化从表对象(Employee)。如果顺序反过来,程序持久化Employee对象时,该对象还没有关联实体,所以Hibernate不能为对应记录的外键列指定值,等到设置关联关系时,Hibernate只能再次使用update语句来修改了。
2.2有连接表的双向1-N关联
有连接表的双向1-N关联。1的一端使用集合元素映射,然后在集合元素中增加
在N的一端使用