这里要说的是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>();
//把两个Employee对象添加到set集合中
emps.add(emp1);
emps.add(emp2);
//为Department对象注入set集合属性
depart.setEmps(emps);
s = HibernateUtil.getSession();
tx = s.beginTransaction();
//保存Department对象
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); //根据ID查询
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()删除当前对象时,会级联删除所有关联的对象。