hibernate 的 关联关系之多对多 和 延迟加载

Posted 寒江孤影,江湖故人,相逢何必曾相识。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate 的 关联关系之多对多 和 延迟加载相关的知识,希望对你有一定的参考价值。

 

一、关联关系 多对多

栗子:一个员工可以有写多个项目,一个项目也是由多个程序员来完成,这就是一个典型的多对多实例

下面给根据实例提取出两个实体类 Employee (员工实体), Project (项目实体)。

一。单向的多对多:(提添加一个项目,并给这个项目添加两个员工。)

在员工表中植入Project属性

 

配置Employee.hbm.xml文件:

开始单侧:

 

 @Test
    //双向多对多关联关系 2.添加多个员工到一个部门下
    public void manytomanyt1(){

        Session session = HibernateUtil.getSession();
        Transaction tx=session.beginTransaction();

        Employee emp=new Employee();
        emp.setEmpname("山鸡");

        Project pro1=new Project();
        pro1.setProname("安防部门");
        Project pro2=new Project();
        pro2.setProname("财务部门");

        emp.getProjects().add(pro1);
        emp.getProjects().add(pro2);

        session.save(emp);
        session.save(pro1);
        session.save(pro2);

        tx.commit();
    }

  结果:

 

二。多对多双向(查询项目下有几个员工/查询每个员工有几个项目)

在项目表中植入员工Employee属性:

配置Project.hbm.xml文件(同上):

 

测试:

 

@Test
    //双向多对多关联关系  1.检索员工姓名并查出项目名称
    public void t(){
        Session session = HibernateUtil.getSession();

        Employee employee = session.get(Employee.class, 29);
        System.out.println("员工名称:"+employee.getEmpname());

        System.out.println("员工所在项目:");

        for (Project project:employee.getProjects()){
            System.out.println(project.getProname());
        }

    }

  

 结果:

Hibernate: 
    select
        employee0_.empid as empid1_2_0_,
        employee0_.empname as empname2_2_0_ 
    from
        ANNAN.Employee employee0_ 
    where
        employee0_.empid=?
员工名称:山鸡
员工所在项目:
Hibernate: 
    select
        projects0_.eid as eid1_5_0_,
        projects0_.pid as pid2_5_0_,
        project1_.proid as proid1_3_1_,
        project1_.proname as proname2_3_1_ 
    from
        empAndPro projects0_ 
    inner join
        ANNAN.Project project1_ 
            on projects0_.pid=project1_.proid 
    where
        projects0_.eid=?
安防部门
财务部门

  

 

二、延迟加载

延迟加载(lazy load懒加载)是当在真正需要数据时,才执行SQL语句进行查询,避免了无谓的性能开销。

 

延迟加载分类:

 

 01.类级别的查询策略

 02.一对多和多对多关联的查询策略

 03.多对一关联的查询策略

 

一。类级别的查询策略立即检索延迟检索默认为延迟检索

 

 //类级别的延迟加载
    @Test
    public void t3(){
//默认lazy为true Session session = HibernateUtil.getSession(); Employee employee = session.load(Employee.class, 29); System.out.println(); }

 效果:

 

 

 当Class类 的lazy为false时:

 

效果:

 

 

 

三、对多和多对多关联查询策略

 

:::::::一对多或者多对多检索策略由lazyfetch共同确定:::::::

 

在映射文件中,用<set>元素来配置一对多关联及多对多关联关系。<set>元素有lazyfetch属性

 

1.lazy的值为true时:延迟加载

 结果:

 

 

2.lazy的值为false时:立即加载

 

 

fetch取值

    Join:迫切左外连接

    Select:多条简单SQL(默认值)

    Subselect:子查询

 

fetchlazy组合

 

  解析:fetch=”join” lazy会被忽略,迫切左外连接的立即检索

 

        Fetch=”select” lazy=”false”  多条简单SQL立即检索

 

        Fetch=”select” lazy=”true”  多条语句延迟检索

 

        Fetch=”select” lazy=”extra”  多条语句及其懒惰检索

 

 

        Fetch=”subselect” lazy=”false”  子查询立即检索

 

        Fetch=”subselect” lazy=”true”  子查询延迟检索

 

        Fetch=”subselect” lazy=”extra”  子查询及其懒惰检索

 

Join:

<set name="projects" table="empAndPro" fetch="join">
Hibernate: 
    select
        employee0_.empid as empid1_2_0_,
        employee0_.empname as empname2_2_0_,
        projects1_.eid as eid1_5_1_,
        project2_.proid as pid2_5_1_,
        project2_.proid as proid1_3_2_,
        project2_.proname as proname2_3_2_ 
    from
        ANNAN.Employee employee0_ 
    left outer join
        empAndPro projects1_ 
            on employee0_.empid=projects1_.eid 
    left outer join
        ANNAN.Project project2_ 
            on projects1_.pid=project2_.proid 
    where
        employee0_.empid=?
员工名称:山鸡
员工所在项目:
财务部门
安防部门

 

 默认select:

<set name="projects" table="empAndPro" fetch="select">
Hibernate: 
    select
        employee0_.empid as empid1_2_0_,
        employee0_.empname as empname2_2_0_ 
    from
        ANNAN.Employee employee0_ 
    where
        employee0_.empid=?
员工名称:山鸡
员工所在项目:
Hibernate: 
    select
        projects0_.eid as eid1_5_0_,
        projects0_.pid as pid2_5_0_,
        project1_.proid as proid1_3_1_,
        project1_.proname as proname2_3_1_ 
    from
        empAndPro projects0_ 
    inner join
        ANNAN.Project project1_ 
            on projects0_.pid=project1_.proid 
    where
        projects0_.eid=?
安防部门
财务部门

 

3.lazy的值为extra时:加强延迟加载:(

只有访问集合对象的属性时才会加载,访问集合本身的属性时(例如,集合大小,生成count),不会立即加载。

)

 

 结果:

System.out.println(projects.size());
Hibernate: 
    select
        employee0_.empid as empid1_2_0_,
        employee0_.empname as empname2_2_0_ 
    from
        ANNAN.Employee employee0_ 
    where
        employee0_.empid=?
Hibernate: 
    select
        count(pid) 
    from
        empAndPro 
    where
        eid =?
2

  

以上是关于hibernate 的 关联关系之多对多 和 延迟加载的主要内容,如果未能解决你的问题,请参考以下文章

关联映射 ---- Hibernate之多对多关系

hibernate关联映射之多对多

hibernate 表关系映射详解之多对多

Mybatis之关联关系(一对多多对多)

Hibernate框架进阶(中篇)之多表关系

Hibernate的多对多关联关系