zoukankan      html  css  js  c++  java
  • Hibernate(四) 关联关系(多对多)和延迟加载

    一·关联关系(多对多)

    举例:一个员工可以开发多个项目,一个项目也可以被多个员工开发

    1.1单向

     

    Project实体
    public class Project {
        private Integer proid;
        private String proname;
    }
    

     Project.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.manytomany.entity">
    
        <class name="Project" table="Project" schema="wy">
    
            <id name="proid" column="proid">
                <generator class="native"/>
            </id>
            <property name="proname" column="proname"></property>
    
    
        </class>
    </hibernate-mapping>
    

      

    Employee 实体
    再该实体中植入项目的实体
    public class Employee {
        private Integer empid;
        private String empname;
        private Set<Project> projects = new HashSet<Project>();
    }
    

     Employeehbm.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.manytomany.entity">
    
        <class name="Employee" table="Employee" schema="wy" lazy="false">
    
            <id name="empid" column="empid">
                <generator class="native"/>
            </id>
            <property name="empname" column="empname"></property>
    
            <set name="projects" table="REmpPro" cascade="save-update">
                <key column="REmpNo"></key>
                <many-to-many class="Project" column="RProNo"></many-to-many>
            </set>
    
        </class>
    </hibernate-mapping>
    

      <set>标签:

        name:被植入的set集合的属性名

        table:多对多的中间表名称

        cascade:(级联)当执行修改和添加时hibernate框架会自动将关联的实体做对应的操作

        key   column:表示中间表中员工的外键

        class:set集合中的属性

        column:集合中元素在中间表的外键

      

    单测:

      @Test
        public void add(){
    
            Session session = HibernateUtil.getSession();
    
            Employee emp1=new Employee();
            emp1.setEmpname("刘黑子");
    
            Project pro1=new Project();
            pro1.setProname("项目1");
            Project pro2=new Project();
            pro2.setProname("项目2");
    
            emp1.getProjects().add(pro1);
            emp1.getProjects().add(pro2);
    
            session.save(emp1);
    
            HibernateUtil.closeSession();
            System.out.println("add ok!");
        }
    

      1.2双向

        在单向的基础上,将项目实体类中也加入员工的实体类集合

      修改后的Project 实体

    public class Project {
        private Integer proid;
        private String proname;
        private Set<Employee> projects = new HashSet<Employee>();
    }
    

      修改后的Project.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.manytomany.entity">
    
        <class name="Project" table="Project" schema="wy">
    
            <id name="proid" column="proid">
                <generator class="native"/>
            </id>
            <property name="proname" column="proname"></property>
            <set name="employees" table="REmpPro">
                <key column="RProNo"></key>
                <many-to-many class="Project" column="REmpNo"></many-to-many>
            </set>
    
        </class>
    </hibernate-mapping>
    

      

    单测:

      @Test
        public void sel(){
    
            Session session = HibernateUtil.getSession();
    
            Employee employee = session.get(Employee.class, 6);
    
            for (Project item:employee.getProjects()){
                System.out.println(item.getProname());
            }
    
    
            HibernateUtil.closeSession();
            System.out.println("sel ok!");
        }
    

      二.延迟加载

      2.1类级别的延迟加载

    立即检索:立即加载检索方法指定的对象,立即发送SQL
    延迟检索:延迟加载检索方法指定的对象.在使用具体的属性时,再进行加载,才发送SQL

    注意:无论<class>元素的lazy属性是true还是falseSessionget()方法及Querylist()方法在类级别总是使用立即检索策略

    同样继续使用上述的实体

    将加载方式改为立即加载

    单测:

     @Test
        public void sel(){
    
            Session session = HibernateUtil.getSession();
            Employee employee = session.load(Employee.class, 6);
            HibernateUtil.closeSession();
            System.out.println("sel ok!");
        }
    

      结果:

    发送了sql

     将加载方式修改为延迟加载

    单测

       @Test
        public void sel(){
    
            Session session = HibernateUtil.getSession();
            Employee employee = session.load(Employee.class, 6);
            HibernateUtil.closeSession();
            System.out.println("sel ok!");
        }

      结果:

    没有sql

    2.2一对多和多对多的延迟加载

    继续使用上述实体

    不延迟加载

    Debug:

    @Test
    public void sel(){

    Session session = HibernateUtil.getSession();
    Employee employee = session.get(Employee.class, 6);
    HibernateUtil.closeSession();
    System.out.println("sel ok!");
    }

      

    加强延迟加载

     Debug

    Test
        public void sel(){
    
            Session session = HibernateUtil.getSession();
            Employee employee = session.load(Employee.class, 6);
            HibernateUtil.closeSession();
            System.out.println("sel ok!");
        }
    

      结果:

    当访问employee的属性时不会加载其中的set<project>集合。当访问set集合的属性时也不会加载,当访问set集合中元素时才会查询

  • 相关阅读:
    全网最深分析SpringBoot MVC自动配置失效的原因
    这一次搞懂Spring代理创建及AOP链式调用过程
    这一次搞懂SpringBoot核心原理(自动配置、事件驱动、Condition)
    这一次搞懂Spring Web零xml配置原理以及父子容器关系
    这一次搞懂SpringMVC原理
    这一次搞懂Spring事务是如何传播的
    Redis系列(八):发布与订阅
    【深度思考】JDK8中日期类型该如何使用?
    【Redis面试题】如何使用Redis实现微信步数排行榜?
    Nacos系列(一):Nacos环境安装及Hello World示例
  • 原文地址:https://www.cnblogs.com/wy0119/p/8150436.html
Copyright © 2011-2022 走看看