Hibernate 基于关联关系的增删改操作

09/04/2010

Hibernate 是一个面向对象的持久化框架,其基于关联关系的增删改操作需要从对象的两端进行
Hibernate 基于关联关系的增删改操作主要包括如下几个方面

  • 在one方添加数据
  • 在many方添加数据
  • 在many方删除数据
  • 修改关联关系 (的inverse属性 设置更新主控方)
  • 在one方删除数据(的cascade属性 级联操作)


下面我们逐一对以上进行分析
1.在one方添加数据 — 对于关联关系无明显影响只需要进行 ONE 方操作即可

	/**
	 * ONE 方增加数据不需要对关联属性进行特别设定
	 * Department department = new Department();
	 * deparement.setDepartmentName("动力部");
	 * @param department
	 */
	public void addDepartment(Department department) {
		super.add(department);
	}

2.在many方添加数据 — 添加新的雇员需要注意:新雇员需要设设定 雇员姓名 雇员所属部门(关联对象)

public class Tester {
	/**
	 * 测试 添加新雇员的操作
	 * 雇员姓名:王华
	 * 雇员部门:计划部
	 * @param args
	 */
	public static void main(String[] args) {
		HrDAO dao = new HrDAO();
		//新建雇员对象
		Employee employee = new Employee();
		//雇员姓名装入
		employee.setEmployeeName("王华");
		//取得 计划部 的部门对象 并装入雇员对象
		List<Department> list = dao.getDepartmentList();
		for(Department department:list) {
			if (department.getDepartmentName().equals("计划部")) {
				employee.setDepartment(department);
				break;
			}
		}
		dao.addEmployee(employee);
	}
}

3.在many方删除数据 — 对于关联关系无明显影响只需要进行 many 方操作即可

public class Tester2 {
	/**
	 * 测试 删除雇员的操作
	 * 雇员姓名:王华
	 * @param args
	 */
	public static void main(String[] args) {
		HrDAO dao = new HrDAO();
		//新建雇员对象
		Employee employee = null;
		//根据雇员姓名装入雇员
		List<Employee> list = dao.getEmployeeList();
		for(Employee e:list) {
			if (e.getEmployeeName().equals("王华")) {
				employee = e;
				break;
			}
		}
		//执行删除
		dao.delEmployee(employee.getEmployeeId());
	}
}

4.修改关联关系 (的inverse属性 设置更新主控方)
注意:在 one-to-many 双向关联关系中,一般我们将 many 方设置为主控方 one 方为被控方(inverse=’true’)

public class Tester3 {
	/**
	 * 测试 更新雇员 王五 的部门信息
	 * 雇员姓名:王五
	 * 原始部门:财务部
	 * 新至部门:制造部
	 * @param args
	 */
	public static void main(String[] args) {
		HrDAO dao = new HrDAO();

		//获得雇员对象
		Employee employee = null;
		//根据雇员姓名装入雇员
		List<Employee> list = dao.getEmployeeList();
		for(Employee e:list) {
			if (e.getEmployeeName().equals("王五")) {
				employee = e;
				break;
			}
		}

		//获得 财务部 制造部 对象
		Department caiwuDepart = null ,zhizaoDepart = null;
		//根据部门名称装入部门对象
		List<Department> depList = dao.getDepartmentList();
		boolean f1 = false , f2 = false;
		for(Department d:depList) {
			if (d.getDepartmentName().equals("财务部")) {
				caiwuDepart = d;
				f1 = true;
			}
			if (d.getDepartmentName().equals("制造部")) {
				zhizaoDepart = d;
				f2 = true;
			}
			if (f1 && f2) {
				break;
			}
		}

		//1.财务部中删除雇员王华的信息
		caiwuDepart.getEmployees().remove(employee);
		//2.制造部中添加雇员王华的信息
		zhizaoDepart.getEmployees().add(employee);
		//2.更新雇员所属部门信息
		employee.setDepartment(zhizaoDepart);

		//更新数据库
		dao.updateEmployee(employee);
	}
}

在以上的例子中:
ONE :财务部对象移除雇员 – 制造部对象增加雇员 的操作是没有意义的!
但是这样逻辑上保证了对象,关系数据库模型的统一性。并且在实际应用中如果部门信息并不是直接有数据库中取出,而是由其他瞬时作用域中得到的话,其操作就具有了实际的保证数据一致性的意义!

5.在one方删除数据(的cascade属性 级联操作)
如果在 ONE 方删除数据,MANY 方相关数据不是就会出现无效数据了吗?
解决方案是在 ONE 方 实体配置文件,关联属性中增加 cascade 属性

<hibernate-mapping>
    <class name="cn.net.royakon.entity.Department" table="department" catalog="hrdb">
        <id name="departmentId" type="java.lang.Integer">
            <column name="department_id" />
            <generator class="identity" />
        </id>
        <property name="departmentName" type="java.lang.String">
            <column name="department_name" length="50" not-null="true" />
        </property>
        <!-- 增加 cascade="all" 属性 所有的 ONE方操作均导致级联更新 -->
        <set name="employees" inverse="true" cascade="all">
            <key>
                <column name="employee_department" not-null="true" />
            </key>
            <one-to-many class="cn.net.royakon.entity.Employee" />
        </set>
    </class>
</hibernate-mapping>
public class Tester4 {
	/**
	 * 测试 删除 财务部
	 * @param args
	 */
	public static void main(String[] args) {
		HrDAO dao = new HrDAO();
		//获得 财务部 对象
		Department caiwuDepart = null;
		//根据部门名称装入部门对象
		List<Department> depList = dao.getDepartmentList();
		for(Department d:depList) {
			if (d.getDepartmentName().equals("财务部")) {
				caiwuDepart = d;
				break;
			}
		}
		//从数据库中删除
		dao.delDepartment(caiwuDepart);
	}
}