连接查询: 关系型数据库之所以强大,其中一个原因就是可以统一使用表来管理同类数据信息,并且可以在相关数据之间建立关系。作为支持关系型数据库的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的各种版本中,只允许在一个查询中迫切左外连接检索一个集合,即只允许存在一个一对多关联,但是允许存在多个一对一和多对多关联。
分享到:
相关推荐
【标题】"7.1.1Hibernate的入门必备——文档和源码"主要涉及的是Java领域的一个重要ORM框架——Hibernate的基础学习。Hibernate是一种用于Java应用的开源对象关系映射(ORM)工具,它允许开发者将Java类与数据库表...
当我们需要进行更复杂的数据库查询时,Hibernate提供了丰富的高级查询功能,这正是“Hibernate的高级查询”这一主题的核心所在。 在Hibernate中,高级查询主要包括HQL(Hibernate Query Language)、Criteria API和...
这是我花费4天的时间做的北大青鸟Hibernate单元练习项目。...如何使用好Criteria限制查询条件、怎样用好和标签,怎样进行增加验证......经历过项目才会对知识有更深层次的掌握,本资料对初学者一定很有帮助。
Hibernate是一个流行的Java对象关系映射(ORM)框架,它极大地简化了Java应用与数据库的交互。然而,Hibernate的性能和效率问题一直是一个需要特别关注的领域。Hibernate自动生成的SQL语句可能在某些情况下并不是最...
Action类是业务逻辑的主要载体,通常会与Hibernate中的DAO(Data Access Object)层交互,完成数据的增删改查操作。 Hibernate则用于管理和操作数据库。在该项目中,它可能定义了News实体类,对应数据库中的新闻表...
在使用Hibernate进行数据查询时,有时会遇到需要使用子查询的情况。然而,正如你所描述的,Hibernate的HQL(Hibernate Query Language)并不直接支持在`FROM`子句后跟一个子查询,这与标准的SQL语法有所差异。在HQL...
2. **比较操作符**:`from Entity e where e.value > (select avg(value) from Entity)`,可以比较当前实体的值与子查询的平均值。 3. **EXISTS/NOT EXISTS**:`from Entity e where exists (select 1 from ...
**正文** Hibernate是一个Java开发中的持久化框架...提供的资源“Hibernate QBC高级查询.wps”应该包含详细的讲解和示例代码,帮助你掌握这些高级技巧。请仔细研读,通过实践来巩固理论知识,提升你的Hibernate技能。
《Struts2、Spring与Hibernate整合应用:学生成绩管理系统》 在IT行业中,构建一个高效、稳定的Web应用程序常常需要整合不同的框架。本项目“学生成绩管理系统”就是基于Struts2、Spring和Hibernate三大主流Java ...
3. **对象关系映射(ORM)**:讲解Hibernate的核心——ORM技术,如何通过注解或XML配置文件将Java类与数据库表进行映射,包括实体类的定义、主键生成策略、属性映射等。 4. **Session和Transaction**:深入理解...
在"JavaEE高级工程师I培训——框架核心技术Struts.Hibernate.Spring"课程中,你将学习到如何有效地利用这三个框架,包括但不限于以下内容: 1. Struts框架的架构设计和工作原理 2. 创建和配置Struts2应用,包括...
**Hibernate使用——入门** Hibernate 是一个强大的开源对象关系映射(ORM)框架,它简化了Java应用程序与数据库之间的交互。这篇博文将引导你入门Hibernate,理解其基本概念和使用方法。 **1. Hibernate概述** ...
Hibernate面试题部分汇总集合Hibernate面试题部分汇总集合
根据提供的文件信息,我们可以深入探讨Hibernate中的连表查询方法及其应用。下面将详细介绍与标题、描述及部分代码相关的几个核心知识点: ### Hibernate 连表查询基础 Hibernate 是一个开源的对象关系映射(ORM)...
在探讨“hibernate过滤器使用例子”这一主题时,我们深入分析了如何在Hibernate框架中运用过滤器功能,以及如何结合分页技术优化数据查询效率。以下将详细阐述相关知识点,包括过滤器的基本概念、配置方法、源码解析...
Hibernate分页查询小结
本文将深入探讨如何在Hibernate中利用查询条件创建List集合,这在处理复杂的数据筛选和聚合时尤其有用。 首先,让我们理解在Hibernate中创建List集合的基本概念。List集合是Java集合框架的一部分,它可以存储有序且...
**hibernate映射与查询** Hibernate 是一个流行的 Java 应用程序开发框架,它提供了一个持久层解决方案,简化了数据库操作。对于初学者来说,理解 Hibernate 的映射和查询机制是至关重要的,因为它们构成了 ...
总结来说,"struts2+hibernate整合例子——新闻管理系统"是一个典型的Java Web应用示例,展示了如何利用Struts2的MVC模式和Hibernate的ORM能力,实现对新闻数据的CRUD操作及高级查询。这个系统可能包含了Action类、...