zoukankan      html  css  js  c++  java
  • Hibernate(三)关联关系 控制属性

    关于多对一,一对多,一对一的解释见我之前写的博客mybatis(三)

      这里介绍的是hibernate中多对一,一对多,一对一的应用。

    Dept实体

    public class Dept {
        private Integer deptno;
        private String deptname;
    }
    

      

    Emp实体

    public class Emp {
        private Integer empno;
        private String empname;
    
        //植入部门单个对象
        private Dept dept;
    }

      

    一. 多对一(many-to-one)

    多对一的配置是在多的一方植入少的一方的实体

    Dept.hbm.xml 文件

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="cn.hibernate.mapping.entity">
    
        <class name="Dept" table="Dept" >
    
            <id name="deptno" column="DEPTNO">
                <generator class="native"/>
            </id>
            <property name="deptname" column="DEPTNAME"></property>
        </class>
    </hibernate-mapping>
    

      这个配置文件没有任何特别之处。也没有关于多对一的配置

    Emp.hbm.xml 文件

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="cn.hibernate.mapping.entity">
    
        <class name="Emp" table="Emp" >
    
            <id name="empno" column="EMPNO">
                <generator class="native"/>
            </id>
            <property name="empname" column="EMPNAME"></property>
    
            <many-to-one name="dept" class="Dept" column="deptno"></many-to-one>
    
        </class>
    </hibernate-mapping>
    

      该文件中出了常规属性的配置外,将植入的少的一方的实体

    在多对一中就使用<many-to-one name="dept" class="Dept" column="deptno"></many-to-one>节点

    name:指的是在实体类中植入的实体的属性名

    Class:指的是该name的类型

    column:指的是在底层数据库中关联另一张表的的列(例:在该环境中就表示与dept表中的deptno关联的列,该列在emp表中)

    单测:

    1.查询一号员工对应的部门

     @Test
        public void sel(){
            Session session = HibernateUtil.getSession();
            Emp emp = session.load(Emp.class, 1);
    
    
            System.out.println(emp.getEmpname());
            System.out.println(emp.getDept().getDeptname());
    
    
            HibernateUtil.closeSession();
    
        }
    

      结果:

    2.保存员工到某个部门下

     @Test
        public void add(){
            Session session = HibernateUtil.getSession();
    
            Dept dept=new Dept();
            dept.setDeptno(1);
    
            Emp emp=new Emp();
            emp.setEmpname("hehehe");
            emp.setDept(dept);
    
            session.save(emp);
    
            HibernateUtil.closeSession();
    
        }

    二.一对多

    在少的一方植入一个HashSet集合

    如:

    public class Dept {
        private Integer deptno;
        private String deptname;
    
        private Set<Emp> emps=new HashSet<Emp>();
    }
    

      在相应的配置文件中加入

     <set name="emps">
                <key column="deptno"></key>
                <one-to-many class="Emp"></one-to-many>
            </set>
    

      相应的:name:为植入得到set集合的属性名

          column:为该集合中的每一项与当前表的那一列有关系

          class:集合中的值是什么类型

    单测:

     @Test
        public void sel(){
            Session session = HibernateUtil.getSession();
    
            String hql="from Dept";
            Query query = session.createQuery(hql);
            List<Dept> list = query.list();
    
            for (Dept dept:list){
                System.out.println(dept.getDeptname());
    
                for (Emp emp:dept.getEmps()){
                    System.out.println(emp.getEmpname());
                }
                System.out.println("================");
            }
    
            HibernateUtil.closeSession();
    
        }
    

      结果:

     三. 一对一

    与多对一非常相似,只是多的一方变为了一

    这时你有两种方案来时实现该用法

    1.假设每一个部门有且只有一个员工,来实现一对一只需要在  员工类和部门类中互相植入对方的属性即可,

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="cn.hibernate.mapping.entity">
    
        <class name="Dept" table="Dept" >
    
            <id name="deptno" column="DEPTNO">
                <generator class="native"/>
            </id>
            <property name="deptname" column="DEPTNAME"></property>
    
            <one-to-one name="emp" class="Emp"></one-to-one>
           
        </class>
    </hibernate-mapping>
    

          Emp.hbm.xml中的<many-to-one name="dept" class="Dept" column="deptno"   unique="true"></many-to-one>标签中设置"unique"="true"。即可

    2.将<many-to-one name="dept" class="Dept" column="deptno"   unique="true"></many-to-one>节点改为

      <one-to-one name="demp" class="Demp"></one-to-one>

     四.控制属性

     Hibernate中控制属性主要有 cascade, inverse , order-by

    1.cascade(级联)

    Cascade取值:None,save-update,delete和all

       none:当Session操纵当前对象时,忽略其他关联的对象。它是cascade属性的默认值.

       Save-update:当通过Session的save()、update()及saveOrUpdate()方法来保存或更新当前对象时,级联保存所有关联的新建的瞬时状态的对象,并且级联更新所有关联的游离状态的对象。

       Delete:当通过Session的delete()方法删除当前对象时,会级联删除所有关联的对象。当通过Session的delete()方法删除当前对象时,会级联删除所有关联的对象。

       All:包含save-update,delete的行为。

      注意点:级联也就是说当我们保存持久化对象A的时候自动帮我们保存持久化对象B。而取值就是他的策略,决定了在什么时候会使用级联

     问题:cascade属性写在什么位置?

      解析:一对一或者多对一的时候,直接写在标签上,其他的写在set标签上。

    2.inverse 

    inverse属性指定了关联关系中的方向。

    inverse设置为false,则为主动方,由主动方负责维护关联关系,默认是false 。

    注意:inverse 决定是否把对对象中集合的改动反映到数据库中,所以inverse只对集合起作用,也就是只对one-to-manymany-to-many有效(因 为只有这两种关联关系包含集合,而one-to-onemany-to-one只含有关系对方的一个引用)。

    Eg.测试代码如下:

    tran = session.beginTransaction();

    //准备一个Department对象

    Department dept=new Department();

    dept.setName("财务部");

    //准备一个Employee对象

    Employee emp=new Employee();

    emp.setName("甄子丹");

    //员工指定自己所属的部分

    emp.setDept(dept);

    dept.getEmployees().add(emp);

    session.save(dept);

    // 事务提交

    tran.commit();

    System.out.println("成功");

    说明:如果我既给员工指定了自己所属的部门,又将员工添加到部门集合中。那么这个时候reverse不设置,生成以下sql

    inverse设置为true,不负责维护关联关系

    观察发现,其实第二条insert语句已经在员工表中指定了自己所属的部分,没有必要再向数据库发送一条update指令。

    将inverse设置成true后,生成的语句如下图所示。

    1.3 order-by

    Hibernate如何对集合中的元素进行排序

    解析:由于使用Hibernate后,生成SQL重任交给了Hibernate,所以Hibernate给我们留了一条绿色通道,可以让我们很容易的对集合中的数据进行排序。那就是使用order-by,使用order-by用于在数据库中对集合进行排序。

    Eg.核心测试代码

    Set集合设置如下:

     <set name="employees" cascade="save-update" inverse="true" order-by="id asc">   

           <key column="deptid"></key> 

           <one-to-many class="Employee"/> 

        </set>

    注意:id是数据库表Employee中的列名,不是持久化类的属性名

    List<Department> list = session.createQuery("from Department").list();

    for (Department dept : list) {

    for (Employee emp : dept.getEmployees()) {

    System.out.println(emp.getId()+" "+emp.getName());

    }

    }

    结果:

    66 张三

    67 李四

    同一个部门下的员工编号按照升序排序

      

     

      

  • 相关阅读:
    [置顶] 【Git入门之十五】Github操作指南
    hdu 3698 Let the light guide us(线段树优化&简单DP)
    拥有最小高度能自适应高度,IE、FF全兼容的div设置
    浏览器小览【欢迎讨论】
    实习心得体会--在一家互联网公司4个月的心得体会
    九度online judge 1543 二叉树
    指令系统是指计算机所能执行的全部指令的集合
    电脑的CPU可直接解读的数据机器码
    解释是一句一句的翻译
    编译解释两种方式只是翻译的时间不同
  • 原文地址:https://www.cnblogs.com/wy0119/p/8135293.html
Copyright © 2011-2022 走看看