Hibernate中的一对多关系详解(2)

一对多的关系:例如,部门对员工,一个部门可以有多个员工

多对一的关系:例如,员工对部门,多个员工属于一个部门,并且每个员工只能属于一个部门

那么一对多、多对一在数据库中的是怎样表示的呢?好多话都不说了,请看下面例子:

public class DeptVo implements Serializable {

    private int deptno;
    private String dname;
    private String loc;
    
    //每个部门中存放的员工  用于一对多
    private Set<EmpVo> employees = new HashSet<EmpVo>();
    ....get  ,set 方法已省略
    
}
public class EmpVo implements Serializable {

    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Float sal;
    private Float comm;
    private Integer deptno;
    
    private DeptVo dept=new DeptVo();//存放部门对象,用于多对一
      ....
    
}
<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE hibernate-mapping PUBLIC
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping package="com.ysq.vo">
    <class name="DeptVo"  table="dept">
       <id name="deptno">
           <generator class="sequence">
              <param name="sequence">dept_seq</param>
           </generator>
       </id>
       <property name="dname"/>
       <property name="loc"/>   
       
       <!--         部门对员工的一对多配置-->
        <set name="employees" inverse="true" cascade="all" lazy="false"><!--inverse="true"让对方维护双方的关系,cascade="all"级联操纵-->
            <key column="deptno"></key><!--column="deptno"指定员工表的外键-->
            <one-to-many class="EmpVo"/>
        </set>             
    </class> 
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE hibernate-mapping PUBLIC
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping package="com.ysq.vo">
      <class name="EmpVo" table="emp">
      <id name="empno">
         <generator class="sequence">
             <param name="sequence">dept_seq</param>
         </generator>
      </id>    
    <property name="ename"/>
    <property name="job"/>
    <property name="mgr"/>
    <property name="hiredate" type="java.sql.Date"/>
    <property name="sal"/>
    <property name="comm"/>
      <!-- 员工对部门的多对一配置 column指定外键-->
  <many-to-one name="dept" class="DeptVo" column="deptno"></many-to-one> 
      
     </class>  
</hibernate-mapping>
public class one_to_many_Test {

    /**
     * 级联添加部门,同时添加对应部门的员工
     */
    @Test
    public void addDeptment(){
        DeptVo dept=new DeptVo();
        dept.setDname("人事部");
        dept.setLoc("5#");
        EmpVo emp1=new EmpVo();
        emp1.setEname("张三");
        emp1.setJob("码农员");
        EmpVo emp2=new EmpVo();
        emp2.setEname("张三2");
        emp2.setJob("主管");
        
        //为员工设置部门
        emp1.setDept(dept);
        emp2.setDept(dept);
        //为部门添加员工
        dept.getEmployees().add(emp1);
        dept.getEmployees().add(emp2);
        
          Session session = SessionFactoryUtils.getSession();
          Transaction tr = session.beginTransaction();
          try {
             tr.begin();
               session.save(dept);//保存部门时,级联保存了部门中的员工
             tr.commit();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            session.close();
        }
    }
    /**
     * 级联删除部门时,删除对应部门中的员工
     */
    @Test
    public void deleteDeptment(){
        
        Session session = SessionFactoryUtils.getSession();
        DeptVo deptment=(DeptVo)session.get(DeptVo.class, 15);
        //获取部门中的员工
        /*Set<EmpVo> emps=deptment.getEmployees();
        deptment.setEmployees(emps);*/
        Transaction tr = session.beginTransaction();
          try {
             tr.begin();
               session.delete(deptment);//删除部门时,级联删除了部门中的员工
             tr.commit();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            session.close();
        } 
    }
    
    /**
     * 级联修改部门,同时修改对应部门的员工
     */
    @Test
    public void updateDeptment(){
        
          Session session = SessionFactoryUtils.getSession();
          Transaction tr = session.beginTransaction();
          //获取要修改部门信息的部门
          DeptVo dept=(DeptVo)session.get(DeptVo.class, 5);
          //获取该部门下的某一员工信息,如empno为6的员工
          EmpVo emp =(EmpVo)session.get(EmpVo.class, 6);
          tr.commit();
          dept.getEmployees().add(emp);//获取部门中的员工,同时将要修改的员工的加进去
          session.close();
          try {
            //重新获得session并重新启动事务
              session=SessionFactoryUtils.getSession();
              tr = session.beginTransaction();
              tr.begin();
            //修改部门信息
              dept.setLoc("4#");
              //修改员工信息
              emp.setEname("无线11");
              //设置双向关联
             // ept.getEmployees()d.add(emp);此句是获取不到部门中的员工的,原因是不在同一个session中,可以用下面的方法
              /*Set emps = new HashSet();
              emps.add(emp);
              dept.setEmployees(emps);*/
              emp.setDept(dept);
              session.update(dept);
             tr.commit();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            session.close();
        }
    }
    /**
     * 查询部门时,同时查询部门的员工
     * 方法一:使用立即加载 在一的配置文件中增加lazy=flase;注意:一对多默认的是延迟加载,即lazy=true
     */
    @Test
    public void selectTest1(){
          Session session = SessionFactoryUtils.getSession();
          Transaction tr = session.beginTransaction();
          DeptVo depts=(DeptVo)session.get(DeptVo.class, 18);//查询部门id为18的
          tr.commit();
           session.close();
           //获取部门下的员工
           Set<EmpVo> emp= depts.getEmployees();
           System.out.println(depts.getDname()+"-----"+emp.size());
    }
    /**
     * 查询部门时,同时查询部门的员工
     * 方法二:使用join fetch加载员工 ,不需要在一的方增加lazy=false;
     */
    @Test
    public void selectTest2(){
          Session session = SessionFactoryUtils.getSession();
          Transaction tr = session.beginTransaction();
          Query q = session.createQuery("from DeptVo d join fetch d.employees where d.deptno=?");//创建一个查询对象
          
          q.setInteger(0, 6);
          DeptVo dept = (DeptVo)q.uniqueResult();
          tr.commit();
          session.close();
          System.out.println("部门名称:"+dept.getDname());
          Set emps = dept.getEmployees();
          for (Iterator iter = emps.iterator(); iter.hasNext();) {
           EmpVo emp = (EmpVo) iter.next();
           System.out.println("员工名字:"+emp.getEname());
          }
    }
    /**
     * 查询所有的部门,同时查询所有的员工
     */
    @Test
    public void selectAll(){
        Session session=SessionFactoryUtils.getSession();
        
       List<DeptVo> list = session.createQuery("from DeptVo").list();
       session.close();
       
       for (DeptVo deptVo : list) {
           Set<EmpVo> emps=deptVo.getEmployees();
           System.out.println(deptVo.getDname()+"_-----------dept");
           if(emps.size()>0){
               for (EmpVo empVo : emps) {
                   System.out.println(empVo.getEname()+"-----emp---");
               }
           }  
       }
    }
}
生活赋予我们一种巨大的和无限高贵的礼品,这就是青春:充满着力量,充满着期待志愿,充满着求知和斗争的志向,充满着希望信心和青春。
原文地址:https://www.cnblogs.com/ysq0908/p/4756044.html