Hibernate(六)实现一对多、多对一映射关联关系

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u011731233/article/details/46906487

一对多、多对一这种关系在现实生活中很多,例如部门与员工的关系,学校里班级与学生的关系...

那么在具体的系统实现中如果i实现这种关联关系呢?这里以部门和员工的关系为例。

部门实体类

package test.hibernate.hbmOneToMany;

import java.util.HashSet;
import java.util.Set;

public class Department {

	private Integer id;
	private String name;
	private Set<Employee> employees = new HashSet<Employee>();

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Set<Employee> getEmployees() {
		return employees;
	}

	public void setEmployees(Set<Employee> employees) {
		this.employees = employees;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "[employee:id=" + id + ",name=" + name + "]";
	}

}
员工实体类

package test.hibernate.hbmOneToMany;

public class Employee {

	private Integer id;
	private String name;
	private Department department=new Department();

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

}
部门映射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="test.hibernate.hbmOneToMany">
	<class name="Department" table="department">
		<id name="id" type="integer" column="id">
			<generator class="native" />
		</id>
		<property name="name" />
		<!-- inverse属性:默认为false,表示本方维护关联关系;
		                                        如果设为true,表示本方不维护关联关系 
		     只是影响是否能设置外键列的值(设成有效值或是null值),对获取信息没有影响                                   
		-->
		<set name="employees" inverse="false">
			<key column="departmentId"></key>
			<one-to-many class="Employee" />
		</set>
	</class>
</hibernate-mapping>

inverse=false




inverse=true




员工映射文件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="test.hibernate.hbmOneToMany">
	<class name="Employee" table="employee">
		<id name="id" type="integer" column="id">
			<generator class="native" />
		</id>
		<property name="name"/>
		<many-to-one name="department" class="Department" column="departmentId"></many-to-one>

	</class>
</hibernate-mapping>
测试类App

package test.hibernate.hbmOneToMany;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class App {

	private static SessionFactory sessionFactory = new Configuration()//
			.configure()//
			.addClass(Department.class)// 添加Hibernate实体类(加载对应的映射文件)
			.addClass(Employee.class)//
			.buildSessionFactory();

	@Test
	public void testSave() throws Exception {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		// --------------------------------------------

		// 构建对象
		Department department = new Department();
		department.setName("开发部");

		Employee employee = new Employee();
		employee.setName("张三");

		Employee employee2 = new Employee();
		employee2.setName("李瑟");

		// 关联起来
		employee.setDepartment(department);
		employee2.setDepartment(department);
		department.getEmployees().add(employee);
		department.getEmployees().add(employee2);

		// 保存
		session.save(department);
		session.save(employee);
		session.save(employee2);

		// --------------------------------------------
		session.getTransaction().commit();
		session.close();
	}

	// 获取到部门关联的员工
	@Test
	public void testGet() throws Exception {
		Session session = sessionFactory.openSession();
		session.beginTransaction();

		// 获取数据
		Department department = (Department) session.get(Department.class, 1);
		System.out.println(department.getId());
		System.out.println(department.getName());
		System.out.println(department.getEmployees());

		session.getTransaction().commit();
		session.close();
	}

	// 解除关联关系
	@Test
	public void testRemoveRelation() throws Exception {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		// --------------------------------------------
		// 从员工解除与部门的关联,也就是员工不再属于任何部门
		// Employee employee=(Employee) session.get(Employee.class, 8);
		// employee.setDepartment(null);

		// 从部门解除员工关系
		Department department = (Department) session.get(Department.class, 1);
		// 要使这句有效,需将映射文件里的inverse设为false,即部门恢复维护关系
		department.getEmployees().clear();

		// --------------------------------------------
		session.getTransaction().commit();
		session.close();
	}

	// 删除部门及对员工的影响
	@Test
	public void testDelete() throws Exception {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		// --------------------------------------------

		// 删除员工,对部门没有影响
		// Employee employee=(Employee) session.get(Employee.class, 9);
		// session.delete(employee);

		/*
		 * 如果没有关联的员工,能删除
		 * 如果有关联的员工且inverse=true,由于不能维护关联关系,会直接执行删除且报异常
		 * 如果有关联的员工且inverse=false,由于可以维护关联关系,会将员工的外键设为null,再删除自己
		 */
		Department department = (Department) session.get(Department.class, 8);
		session.delete(department);

		// --------------------------------------------
		session.getTransaction().commit();
		session.close();
	}
}






级联是指操作主对象时,对关联的对象也做相同的操作。 默认为none,代表不级联。可设为:delete、save-update、all、none... 一般在多对一或一对多的时候使用级联,多对多的时候不使用级联。

修改后的测试代码:

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="test.hibernate.hbmOneToMany">
	<class name="Department" table="department">
		<id name="id" type="integer" column="id">
			<generator class="native" />
		</id>
		<property name="name" />
		<!-- inverse属性:默认为false,表示本方维护关联关系;
		                                        如果设为true,表示本方不维护关联关系 
		     只是影响是否能设置外键列的值(设成有效值或是null值),对获取信息没有影响        
		  cascade级联属性:
		  即删掉一个Department,会同时删掉department下的所有employees                          
		-->
		<set name="employees" inverse="false" cascade="save-update">
			<key column="departmentId"></key>
			<one-to-many class="Employee" />
		</set>
	</class>
</hibernate-mapping>
package test.hibernate.hbmOneToMany;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class App {

	private static SessionFactory sessionFactory = new Configuration()//
			.configure()//
			.addClass(Department.class)// 添加Hibernate实体类(加载对应的映射文件)
			.addClass(Employee.class)//
			.buildSessionFactory();

	@Test
	public void testSave() throws Exception {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		// --------------------------------------------

		// 构建对象
		Department department = new Department();
		department.setName("开发部");

		Employee employee = new Employee();
		employee.setName("张三");

		Employee employee2 = new Employee();
		employee2.setName("李瑟");

		// 关联起来
		employee.setDepartment(department);
		employee2.setDepartment(department);
		department.getEmployees().add(employee);
		department.getEmployees().add(employee2);

		// 保存
//		session.save(department);
//		session.save(employee);
//		session.save(employee2);
		
		//级联保存,将cascade设为save-update
		session.save(department);

		// --------------------------------------------
		session.getTransaction().commit();
		session.close();
	}

	// 获取到部门关联的员工
	@Test
	public void testGet() throws Exception {
		Session session = sessionFactory.openSession();
		session.beginTransaction();

		// 获取数据
		Department department = (Department) session.get(Department.class, 1);
		System.out.println(department.getId());
		System.out.println(department.getName());
		System.out.println(department.getEmployees());

		session.getTransaction().commit();
		session.close();
	}

	// 解除关联关系
	@Test
	public void testRemoveRelation() throws Exception {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		// --------------------------------------------
		// 从员工解除与部门的关联,也就是员工不再属于任何部门
		// Employee employee=(Employee) session.get(Employee.class, 8);
		// employee.setDepartment(null);

		// 从部门解除员工关系
		Department department = (Department) session.get(Department.class, 1);
		// 要使这句有效,需将映射文件里的inverse设为false,即部门恢复维护关系
		department.getEmployees().clear();

		// --------------------------------------------
		session.getTransaction().commit();
		session.close();
	}

	// 删除部门及对员工的影响
	@Test
	public void testDelete() throws Exception {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		// --------------------------------------------

		// 删除员工,对部门没有影响
		// Employee employee=(Employee) session.get(Employee.class, 9);
		// session.delete(employee);

		/*
		 * 如果没有关联的员工,能删除
		 * 如果有关联的员工且inverse=true,由于不能维护关联关系,会直接执行删除且报异常
		 * 如果有关联的员工且inverse=false,由于可以维护关联关系,会将员工的外键设为null,再删除自己
		 */
		Department department = (Department) session.get(Department.class, 10);
		session.delete(department);

		// --------------------------------------------
		session.getTransaction().commit();
		session.close();
	}
}


原文出处:http://blog.csdn.net/lindonglian/article/details/46906487

展开阅读全文

没有更多推荐了,返回首页