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集合中元素时才会查询

原文地址:https://www.cnblogs.com/wy0119/p/8150436.html