Hibernate关联关系映射之一对多关联关系
程序员文章站
2022-05-27 11:28:18
...
本次以一个示例方式进行演示,某个单位有多个部门,每个部门中又有很多不同的员工,在存储时需要建立一张员工表和一张部门表,存储全部的部门和员工信息,而这两张表中通过外键进行关联,从而能根据部门名称查询出该部门的所有员工,同时又能根据员工名称查
本次以一个示例方式进行演示,某个单位有多个部门,每个部门中又有很多不同的员工,在存储时需要建立一张员工表和一张部门表,存储全部的部门和员工信息,而这两张表中通过外键进行关联,从而能根据部门名称查询出该部门的所有员工,同时又能根据员工名称查询出他所在的部门。
不难看出部门与员工之间的关系是一对多的关系,相反,员工与部门之间的关系是多对一的关系。
在POJO类和映射文件自然想到使用Set集合表示一对多。
下面看一些部门类Department类
package entity; import java.util.HashSet; import java.util.Set; public class Department { private Integer id; private String name; private Setemployees = new HashSet (); 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 getEmployees() { return employees; } public void setEmployees(Set employees) { this.employees = employees; } }
该类中使用Set集合存储员工信息,表示一个部门中有多个员工。
然后看员工类。
package entity; public class Employee { private Integer id; private String name; private Department 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类的属性,表示一个员工只能属于一个部门。
下面看一下他们的映射文件的配置。
首先看Department.hbm.xml
其中使用
然后看Employee.hbm.xml
这里通过
然后他们之间的映射关系已经搭建完毕,下面看一下测试类,使用JUtil进行测试。
package test; import static org.junit.Assert.*; import java.util.Iterator; import java.util.Set; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import entity.Department; import entity.Employee; import factory.HibernateSessionFactory; public class Test { private Session session = null; private Transaction tran = null; //保存对象 @org.junit.Test public void test() { session = HibernateSessionFactory.getSession(); tran = session.beginTransaction(); try { //新建对象 Department de = new Department(); de.setId(3); de.setName("研发部"); Employee e1 = new Employee(); e1.setId(1); e1.setName("张三"); Employee e2 = new Employee(); e2.setId(2); e2.setName("李四"); //建立关系映射 de.getEmployees().add(e1); de.getEmployees().add(e2); e1.setDepartment(de); e2.setDepartment(de); //保存数据 session.save(de); session.save(e1); session.save(e2); tran.commit(); } catch (Exception e) { tran.rollback(); } } //根据部门查询员工 @org.junit.Test public void getDepartment() { session = HibernateSessionFactory.getSession(); String hql = "FROM Department d where d.id = 2"; Query query = session.createQuery(hql); Department de = (Department) query.uniqueResult(); Setset = de.getEmployees(); Iterator it = set.iterator(); while (it.hasNext()) { Employee e = (Employee) it.next(); System.out.println(e.getName()); } } //根据员工查询部门 @org.junit.Test public void getEmployee() { session = HibernateSessionFactory.getSession(); String hql = "FROM Employee e where e.id=1"; Query query = session.createQuery(hql); Employee e = (Employee) query.uniqueResult(); System.out.println(e.getName() + "属于" + e.getDepartment().getName()); } // 解除关联关系,相当于某一个员工离开原来部门,并不删除两个表中数据 // 从员工方删除 @org.junit.Test public void removeRelation() { session = HibernateSessionFactory.getSession(); tran = session.beginTransaction(); try { Department de = new Department(); de.setId(1); de.setName("宣传部"); session.save(de); Employee e = (Employee) session.get(Employee.class, 3); e.setDepartment(de); session.save(e); tran.commit(); } catch (Exception e) { tran.rollback(); } } // 删除员工方 @org.junit.Test public void deleteEmployee() { session = HibernateSessionFactory.getSession(); tran = session.beginTransaction(); try { Employee e = (Employee) session.get(Employee.class, 4); session.delete(e); tran.commit(); } catch (Exception e) { tran.rollback(); } } // 删除部门 @org.junit.Test public void deleteDepartment() { session = HibernateSessionFactory.getSession(); tran = session.beginTransaction(); try { Department de = (Department) session.get(Department.class, 1); /* * 如果没有关联的员工,能删除 * 如果有关联的员工,且inverse属性为true,由于由不能维护关联,所以会直接执行删除,就会有异常 * 如果有关联的与昂,且inverse属性为false,由于可以维护关联关系,他就会先把关联的员工的外键设为null。在删除 */ session.delete(de); tran.commit(); } catch (Exception e) { tran.rollback(); } } }