`
jfkang
  • 浏览: 18407 次
  • 性别: Icon_minigender_1
  • 来自: 江西
最近访客 更多访客>>
社区版块
存档分类
最新评论

[转载]hibernate检索策略

阅读更多
转自:http://www.blogjava.net/ghyghost/archive/2007/09/10/143890.html

连接查询:
   关系型数据库之所以强大,其中一个原因就是可以统一使用表来管理同类数据信息,并且可以在相关数据之间建立关系。作为支持关系型数据库的SQL语句来说,自然要对全面发挥这种强大功能提供支持,这个支持就是连接查询。同样作为一种关系型数据库的持久层框架,Hibernate也对连接查询提供了丰富的支持,在Hibernate中通过HQL与QBC两种查询方式都可以支持连接查询。下面这一部分我们将通过这两种查询技术,来详细讨论有关Hibernate对连接查询支持的各个细节。在讲解连接查询之前,我们先来回忆一下在第一部分中讲解的有关实体关联关系的映射,在实体的配置文件中可以通过配置集合元素来指定对关联实体的映射以及检索策略。(请参考第一部分相关内容)因此我们可以在实体映射配置文件中,指定关联实体检索策略,对关联实体的检索策略可以指定为“延迟检索”,“立即检索”,“迫切左外连接检索”,如下所示对与Customer实体关联的Order实体设置延迟加载:<set name=”orders” inverse=”true” lazy=”true”>,这种在实体映射配置文件中设定的检索策略,称为默认检索策略,但是这种默认检索策略是可以被覆盖的,那就是在程序代码当中可以动态指定各种迫切检索策略来覆盖默认检索策略。
1、    迫切左外连接查询和左外连接查询:
我们看以下代码,这段代码将覆盖映射文件中的检索策略,显示指定采用迫切左外连接查询。

HQL查询方式:
Query query=session.createQuery(“from Customer c left join fetch c.orders o where c.name       like ‘zhao%’ ”);
List list=query.list();
for(int i=0;i<list.size();i++){
Customer customer=(Customer)list.get(i);
}
//QBC检索方式:
List list=session.createCriteria(Customer.class).setFetchMode(“orders”,FetchMode.EAGER)
        .add(Expression.like(“name”,”zhao%”,MatchMode.START).list();
for(int i=0;i<list.size();i++){
Customer customer=(Customer)list.get(i);
}
我们看到在HQL以及QBC查询中分别通过left join fetch和FetchMode.EAGER来指定采用迫切左外连接检索策略,当采用了迫切左外连接检索策略时,当进行检索时即执行查询的list()方法时,将会立即初始化用来容纳关联实体的集合对象元素,如果在实体映射配置文件中对关联实体设置了延迟加载,那么此时将会忽略延迟加载设置,而采用迫切左外连接策略,并且立即用关联实体对象填充集合对象元素,即使用Order对象填充Customer对象的orders集合。因此这种检索策略会马上创建关联实体对象,此时我想你一定会想到这种检索策略会同时检索出Customer和Order实体对象对应的数据,并且分别创建这两个对象。恭喜你答对了,因此上面代码会生成类似如下的SQL语句:
Select * from customer c left join order o on c.id=o.id where c.name like ‘zhao%’;
如果我们忽略了fetch关键字,就变成了左外连接查询,如下面代码:
Query query=session.createQuery(“from Customer c left join c.orders o where c.name       like ‘zhao%’ ”);
List list=query.list();
for(int i=0;i<list.size();i++){
Object[] objs=(Object[])list.get(i);
Customer customer=(Customer) objs[0];
order order=(Order)objs[1];
}
我们可以看到采用左外连接查询返回的结果集中包含的是对象数组,对象数组中的每个元素存放了一对相互关联的Customer对象和Order对象,而迫切左外连接会返回Customer对象,与Customer对象相关联的Order对象存放在Customer对象的集合元素对象中,这就是迫切左外连接和左外连接查询的其中一个区别(这两种检索生成的SQL语句是一样的),另一个区别是当使用左外连接时,对关联对象的检索会依照实体映射配置文件所指定的策略,而不会像迫切左外连接那样忽略它,比如此时对Customer对象关联的Order对象采用延迟加载,那么左外连接检索也会使用延迟加载机制检索Order对象。
2、内连接,迫切内连接以及隐式内连接:
若采用迫切内连接通过一下代码可以实现:
Query query=session.createQuery(“from Customer c inner join fetch c.orders o where c.name       like ‘zhao%’ ”);
List list=query.list();
for(int i=0;i<list.size();i++){
Customer customer=(Customer)list.get(i);
}
这段代码将会采用迫切内连接检索,对集合元素的检索策略以及返回结果集中的对象类型都采用与迫切左外连接一样的方式,我这里就不再赘述,另外QBC查询不支持迫切内连接检索。
如果去掉fetch就是内连接检索,如下面代码:
Query query=session.createQuery(“from Customer c innerjoin c.orders o where c.name       like ‘zhao%’ ”);
List list=query.list();
for(int i=0;i<list.size();i++){
Object[] objs=(Object[])list.get(i);
Customer customer=(Customer) objs[0];
order order=(Order)objs[1];
}
内连接检索,对集合元素的检索策略以及返回结果集中的对象类型都采用与左外连接一样的方式,QBC查询也同样支持内连接检索,如下代码:
List list=session.createCriteria(Customer.class)
.add(Expression.like(“name”,”zhao%”,MatchMode.START))
.createCriteria(“orders”)
.add(Expression.like(“ordernumber”,”T”,MatchMode.START)).list();
      上面代码等价于如下的HQL语句:
      Select c from Customer c join c.orders o where c.name like ‘zhao%’ and o.ordernummber like ‘T%’;因此可以采用下面的方式访问结果集:
for(int i=0;i<list.size();i++){
Customer customer=(Customer)list.get(i);
}
      由此可见,采用内连接查询时,HQL与QBC查询有不同的默认行为,HQL会检索出成对的Customer和Order对象,而QBC仅会检索出Customer对象。如果QBC查询想检索出成对的Customer和Order对象,可以采用如下代码:
List list=session.createCriteria(Customer.class)
.createAlias(“orders”,”o”)
.add(Expression.like(“this.name”,”zhao%”,MatchMode.START))
.add(Expression.like(“ordernumber”,”T”,MatchMode.START))
.returnMap()
.list();
for(int i=0;i<list.size();i++){
   Map map=(Map)list.get(i);
Customer customer=(Customer)map.get(“this”);
order order=(Order)map.get(“o”);
}
    “o”和”this”分别是orders集合和Customer对象的别名。
    在HQL查询中,还有一种查询成为隐式内连接,我们看下面的HQL语句,
      From order o where o.customer.name like ’ zhao% ’;这个语句通过o.customer.name访问与Order对象关联的Customer对象的name属性,尽管没有使用join关键字,其实隐式指定了采用内连接检索,它和下面这条HQL语句等价:
From order o join o.customer c where c.name like ‘zhao%’;
隐式内连接只适用于多对一和一对一关联,不适用于一对多和多对多关联,另外QBC查询不支持隐式内连接检索。
3、右外连接检索:
由于fetch关键字只能应用于innner join和left join,因此对于右外连接检索而言,就不存在所谓的迫切右外连接查询了,使用右外连接见如下代码:
Query query=session.createQuery(“from Customer c right join c.orders o where c.name       like ‘zhao%’ ”);
List list=query.list();
for(int i=0;i<list.size();i++){
Object[] objs=(Object[])list.get(i);
Customer customer=(Customer) objs[0];
order order=(Order)objs[1];
}
      右外连接检索,对集合元素的检索策略以及返回结果集中的对象类型都采用与左外连接一样的方式。
4、交叉连接:
对于不存在关联关系的两个实体对象,不能使用内连接查询,也不能使用外连接查询,此时可以使用具有SQL风格的交叉连接,如下面代码:
Select c.ID,c.name,c.age,o.ID,o.ordernumber,o.customer_ID
From Customer c,Order o;
这个HQL语句将会执行交叉连接检索,而且将会返回customer表和order表的笛卡儿积关联结果。
5、连接查询运行时检索策略总结:
①、如果在HQL和QBC查询中没有指定检索策略,那么将会使用映射配置为件中指定的检索策略,但是这里有一个例外,那就是HQL检索总是会忽略实体映射配置文件中对关联实体指定的迫切左外连接检索策略,也就是说如果配置文件中指定对关联实体采用迫切走外连接检索,但是在HQL查询语句中没有指定这种检索策略,此时Hibernate将会忽略这种检索策略,而依然采用立即检索。因此如果希望采用迫切左外连接检索,就必须在HQL语句中明确指定。
②、如果在HQL或者QBC检索中明确指定了检索策略,就会覆盖配置文件中的默认检索策略,在HQL查询中通过left join fetch和inner join fetch来明确指定检索策略,在QBC查询中通过FetchMode.DEFAULT,FetchMode.EAGER,FetchMode.LAZY来明确指定检索策略。
①、             目前的Hibernate的各种版本中,只允许在一个查询中迫切左外连接检索一个集合,即只允许存在一个一对多关联,但是允许存在多个一对一和多对多关联。
分享到:
评论

相关推荐

    HIBERNATE检索策略

    标题:“HIBERNATE检索策略” 描述:本文深入解析了HIBERNATE的检索策略,为读者提供了一条清晰的学习路径,重点分析了HIBERNATE中的抓取策略及其应用场景,帮助开发者更有效地管理和优化数据加载过程。 在...

    Hibernate的检索策略

    ### Hibernate的检索策略详解 #### 一、概述 在Java持久化框架Hibernate中,检索策略是一种重要的机制,它主要用于控制对象何时以及如何加载到应用程序内存中。合理的检索策略不仅可以提高应用性能,还能简化代码...

    hibernate5--4.检索方式及策略

    一、Hibernate检索方式 1. **HQL(Hibernate Query Language)**: HQL是Hibernate提供的面向对象的查询语言,类似于SQL,但它是基于类和对象的。你可以通过HQL来查询、更新和删除对象,而无需关心底层的SQL语法。...

    Hibernate主键策略-sequence

    在Java的持久化框架Hibernate中,主键策略是管理数据库记录唯一标识的重要组成部分。主键策略定义了如何生成和管理实体对象的主键值。在本篇内容中,我们将深入探讨"Hibernate主键策略-sequence",并结合标签中的...

    day36-hibernate检索和优化 02-Hibernate检索方式:简单查询及别名查询

    本教程将深入探讨"day36-hibernate检索和优化 02-Hibernate检索方式:简单查询及别名查询"的主题,通过源码分析和实际工具的应用,来提升数据库查询的效率。 首先,我们了解Hibernate的检索方式。在Hibernate中,...

    java-Hibernate 检索

    Hibernate 是一个流行的 Java 持久层框架,它提供了多种检索数据的方式,包括导航对象图检索、OID 检索、HQL 检索、QBC 检索和本地 SQL 检索等。下面将详细介绍每种检索方式。 一、导航对象图检索 导航对象图检索...

    Hibernate数据检索(HQL)笔记

    ### Hibernate数据检索(HQL)知识点详解 #### 一、简介 Hibernate 是一款开源的对象关系映射(ORM)框架,它允许开发人员将 Java 对象映射到数据库表中的记录,从而极大地简化了数据访问层的开发工作。本文档基于...

    day36 04-Hibernate检索方式:多表连接查询

    标题中的“day36 04-Hibernate检索方式:多表连接查询”表明这是一个关于Hibernate框架的教程,重点讲解如何在Hibernate中进行多表连接查询。在这个主题中,我们将深入探讨Hibernate的ORM(对象关系映射)机制以及...

    Hibernate数据检索(HQL)笔记

    Hibernate 数据检索(HQL)笔记 Hibernate 数据检索(HQL)笔记是 Hibernate 框架中的一种查询语言,用于检索数据库中的数据。HQL(Hibernate Query Language)是一种面向对象的查询语言,能够对数据库进行复杂的...

    常用Hibernate主键生成策略

    ### 常用Hibernate主键生成策略详解 #### 一、引言 在数据库设计与操作过程中,主键是确保数据唯一性的关键要素之一。在实际应用中,开发者经常需要处理不同类型的数据库,并且需要应对各种不同的主键生成需求。...

    基于Spring的Hibernate Search全文检索功能示例

    3. **Hibernate Search**:作为Hibernate的一个扩展,Hibernate Search提供了基于Lucene的全文检索功能,使得在数据库中的数据可以被快速、精确地搜索。 **二、集成Hibernate Search** 1. **配置依赖**:首先,你...

    Hibernate各种主键生成策略与配置详解

    关于Hibernate的各种主键生成策略与配置详解

    Hibernate中主键生成策略

    在Java的持久化框架Hibernate中,主键生成策略是一个至关重要的概念,它决定了数据库表中主键值如何自动生成。主键通常是表中唯一标识记录的一列,对于数据的完整性和一致性至关重要。以下是对Hibernate中主键生成...

    hibernate抓取策略和懒加载案例

    在Java的持久化框架Hibernate中,数据访问优化是至关重要的,而抓取策略(Fetch Strategy)和懒加载(Lazy Loading)则是实现这一目标的关键技术。本文将深入探讨这两个概念,并通过具体的案例进行分析。 首先,让...

    hibernate主键生成策略

    【hibernate主键生成策略】是Hibernate框架中用于生成持久化对象主键的重要机制,它决定了如何在数据库中创建唯一的标识符。在SSH(Spring、Struts、Hibernate)架构中,Hibernate作为持久层框架,主键生成策略的...

    Hibernate缓存策略

    Hibernate缓存原理及调优策略 Hibernate缓存原理调优策略

    hibernate的检索

    【Hibernate检索策略】 Hibernate提供三种主要的检索策略:立即检索、延迟检索和迫切左外连接检索。 1. **立即检索**:这种策略将立即加载关联的对象,无论对象是持久化状态还是游离状态。优点是应用程序可以方便...

Global site tag (gtag.js) - Google Analytics