这里要说的是Hibernate的关联关系的级联操作,使用cascade属性控制。
依然用部门和员工举例,多个员工对应一个部门(多对一关联关系)
员工类:Employee.java
- package cn.itcast.hibernate.domain;
-
- public class Employee {
- private int id;
- private String name;
- private Department depart;
-
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Department getDepart() {
- return depart;
- }
- public void setDepart(Department depart) {
- this.depart = depart;
- }
- }
员工类映射文件:Employee.hbm.xml
- <?xml version="1.0"?>
- <!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping
- package="cn.itcast.hibernate.domain">
- <class name="Employee" table="tb_Employee">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name" />
- <many-to-one name="depart" column="depart_id" />
- </class>
-
- </hibernate-mapping>
部门类:Department.java
- package cn.itcast.hibernate.domain;
-
- import java.util.Set;
-
- public class Department {
- private int id;
- private String name;
- private Set<Employee> emps;
-
- public Set<Employee> getEmps() {
- return emps;
- }
- public void setEmps(Set<Employee> emps) {
- this.emps = emps;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
部门映射文件:Department.hbm.xml
- <?xml version="1.0"?>
- <!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping
- package="cn.itcast.hibernate.domain">
-
- <class name="Department" table="tb_Department">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name" />
-
- <set name="emps" cascade="save-update">
- <key column="depart_id" />
- <one-to-many class="Employee" />
- </set>
- </class>
-
- </hibernate-mapping>
可以看到,在上边的set标签中,我们定义了cascade="save-update"属性,当session通过save(),update(),saveOrUpdate()方法来保存或更新对象时,级联保存所有关联的新建的临时对象,并且级联更新所有关联的游离对象
我们来写一个测试类:Many2One.java
- package cn.itcast.hibernate;
-
- import java.util.HashSet;
- import java.util.Set;
-
- import org.hibernate.Hibernate;
- import org.hibernate.Session;
- import org.hibernate.Transaction;
-
- import cn.itcast.hibernate.domain.Department;
- import cn.itcast.hibernate.domain.Employee;
-
- public class Many2One {
- public static void main(String[] arg){
- Department depart = add();
-
- delete(1);
- }
-
- static Department add(){
- Session s = null;
- Transaction tx = null;
- try{
- Department depart = new Department();
-
- depart.setName("depart name");
-
- Employee emp1 = new Employee();
- emp1.setDepart(depart);
- emp1.setName("emp name");
-
-
- Employee emp2 = new Employee();
- emp2.setDepart(depart);
- emp2.setName("emp name");
-
-
- Set<Employee> emps = new HashSet<Employee>();
-
- emps.add(emp1);
- emps.add(emp2);
-
- depart.setEmps(emps);
-
- s = HibernateUtil.getSession();
- tx = s.beginTransaction();
-
-
- s.save(depart);
-
- tx.commit();
- return depart;
- }finally{
- if(s!=null){
- s.close();
- }
- }
- }
-
- static Department delete(int departId){
- Session s = null;
- Transaction tx = null;
- try{
- s = HibernateUtil.getSession();
- tx = s.beginTransaction();
- Department depart = (Department)s.get(Department.class, departId);
- s.delete(depart);
-
- tx.commit();
- return depart;
- }finally{
- if(s!=null){
- s.close();
- }
- }
- }
- }
可以看到我们定义了两个方法:add()和delete()
add():在这个方法中,我们在保存的时候仅仅保存了Department对象,但是根据cascade="save-update"属性,两个Employee对象也会保存在数据库中
delete():在这个方法中,我们想通过直接删除Department对象使得数据库中与Department表关联的Employee表中的数据删除。但是,我们配置的cascade是要求在保存或者更新的时候发生级联关系,所以如果我们执行delete()方法后,只会在Department表的数据被删除,Employee表的数据的外键会变成null,但是数据不会被删除
下边我们来看下cascade的取值:
Cascade属性的取值有:
1、none:忽略其他关联的对象,默认值。
2、save-update:当session通过save(),update(),saveOrUpdate()方法来保存或更新对象时,级联保存所有关联的新建的临时对象,并且级联更新所有关联的游离对象。
3、persist:当session通过persist()方法来保存当前对象时,会级联保存所有关联的新建的临时对象。
4、merge:通过Session的merge()方法来保存当前对象时,会级联融合所有关联的游离对象。
5、delete:通过delete()删除当前对象时,会级联删除所有关联的对象。
6、lock:通过lock()把当前游离对象加入session缓存时,会把所有的游离对象也加入Session缓存中。
7、replicate:通过replicate()复制当前对象时,会级联复制所有关联的对象。
8、evict:通过evict()清除session缓存中对象时,会级联清除所有关联的对象。
9、refresh:通过refresh()刷新当前对象时,会级联刷新所有关联的对象。(刷新是指同步更新session缓存中数据)
10、all:save-update(),persist(),merge(),delete(),lock(),replicate(),evict()及refresh()的行为。
11、delete-orphan,删除所有和当前对象时,解除关联行为的对象。
12、all-delete-orphan; 通过delete()删除当前对象时,会级联删除所有关联的对象。