cascade属性
问题:如何实现添加部门的同时自动添加员工?
解析:可以使用cascade(级联)方式
Cascade取值:
None,save-update,delete和all
none:当Session操纵当前对象时,忽略其他关联的对象。它是cascade属性的默认值.
Save-update:当通过Session的save()、update()及saveOrUpdate()方法来保存或更新当前对象时,级联保存所有关联的新建的瞬时状态的对象,并且级联更新所有关联的游离状态的对象。
Delete:当通过Session的delete()方法删除当前对象时,会级联删除所有关联的对象。
当通过Session的delete()方法删除当前对象时,会级联删除所有关联的对象。
All:包含save-update,delete的行为。
注意点:级联也就是说当我们保存持久化对象A的时候自动帮我们保存持久化对象B。
Eg.测试代码的核心部分
tran = session.beginTransaction();
//准备一个Department对象
Department dept=new Department();
dept.setName("软件部");
//准备一个Employee对象
Employee emp=new Employee();
emp.setName("张靓颖");
dept.getEmployees().add(emp);
session.save(dept);
// 事务提交
tran.commit();
总结:从上述代码中可以看出,我们并没有保存emp对象的代码,但是结果emp对象却被保存到了数据库中。
问题:cascade属性写在什么位置?
解析:一对一或者多对一的时候,直接写在标签上,其他的写在set标签上。
级联保存常见错误
解析:瞬时态的对象在刷新缓存前,必须被保存!
set元素的inverse属性
inverse属性指定了关联关系中的方向。
inverse设置为false,则为主动方,由主动方负责维护关联关系,默认是false 。
注意:inverse 决定是否把对对象中集合的改动反映到数据库中,所以inverse只对集合起作用,也就是只对one-to-many或many-to-many有效(因 为只有这两种关联关系包含集合,而one-to-one和many-to-one只含有关系对方的一个引用)。
Eg.测试代码如下:
tran = session.beginTransaction();
//准备一个Department对象
Department dept=new Department();
dept.setName("财务部");
//准备一个Employee对象
Employee emp=new Employee();
emp.setName("甄子丹");
//员工指定自己所属的部分
emp.setDept(dept);
dept.getEmployees().add(emp);
session.save(dept);
// 事务提交
tran.commit();
System.out.println("成功");
说明:如果我既给员工指定了自己所属的部门,又将员工添加到部门集合中。那么这个时候reverse不设置,生成以下sql
inverse设置为true,不负责维护关联关系
观察发现,其实第二条insert语句已经在员工表中指定了自己所属的部分,没有必要再向数据库发送一条update指令。
将inverse设置成true后,生成的语句如下图所示。
order-by
Hibernate如何对集合中的元素进行排序
解析:由于使用Hibernate后,生成SQL的重任交给了Hibernate,所以Hibernate给我们留了一条绿色通道,可以让我们很容易的对集合中的数据进行排序。那就是使用order-by,使用order-by用于在数据库中对集合进行排序。
Eg.核心测试代码
Set集合设置如下:
<set name="employees"cascade="save-update"inverse="true"order-by="id asc">
<key column="deptid"></key>
<one-to-many class="Employee"/>
</set>
注意:id是数据库表Employee中的列名,不是持久化类的属性名
List<Department> list = session.createQuery("from Department").list();
for (Department dept : list) {
for (Employee emp :dept.getEmployees()) {
System.out.println(emp.getId()+"\t"+emp.getName());
}
}