`
sumongh
  • 浏览: 226500 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论
阅读更多
传统的SQL语言采用的是结构化的查询方法,而这种方法对于查询以对象形式存在的数据却无能为力。幸运的是,Hibernate为我们提供了一种语法类似于SQL的语言,Hibernate查询语言(HQL),和SQL不同的是,HQL是一种面向对象的查询语言,它可以查询以对象形式存在的数据。因此,本文就HQL如何工作以及如何使用HQL展开了深入的讨论。 

  SQL本身是非常强大的。当SQL的这种强大和处理面向对象数据的能力相结合时,就产生了HQL。和SQL一样,HQL提供了丰富的查询功能,如投影查询、聚合函数、分组和约束。任何复杂的SQL都可以映射成HQL。

  本文的第一部分将讨论HQL的简单用法。第二部分将讨论在HQL中如何根据上下文关系进行查询。在第三部分将以一个例子来说明如何在实际应用中使用HQL。

  进入HQL世界

  一个ORM框架是建立在面向对象的基础上的。最好的例子是Hibernate如何提供类SQL查询。虽然HQL的语法类似于SQL,但实际上它的查询目标是对象。HQL拥有面向对象语言的所有的特性,这其中包括多态、继承和组合。这就相当于一个面向对象的SQL,为了提供更强大的功能,HQL还提供了很多的查询函数。这些函数可以被分为四类:

  1. 投影函数

  2. 约束函数

  3. 聚合函数

  4. 分组函数

  使用HQL可以建立简单的查询,也可以建立更复杂的查询。在本文中并不讨论那些非常复杂的查询,如含有子查询和很多连接的查询。本文只讨论连接两个表的查询。现在让我们开始接近HQL吧!

  投影

  如谓投影,就是一个可以访问的对象或对象的属性。在HQL中,可以使用from和select子句来完成这个工作。

  from子句返回指定的类的所有实例。如from Order将返回Order类的所有实例。换句话说,以上的查询相当于以下的SQL语句:

select * from order

  from 是最简单的查询子句。from后面可以跟一个或多个类名(类名也可以带有别名)。为了得到Order和Product的所有实例,可以使用如下的查询:

from Order, Product

  和类名一样,别名也可以在from后使用,如下代码如示:

from Order as o, Product p

  当查询很复杂时,加入别名可以减少语句的长度。我们可以看看如下的SQL语句:

select o.*, p.* from order o, product p where o.order_id = p.order_id

  我们可以很容易看出,上面的查询是一对多的关系。在HQL中相当于一个类中包含多个其它类的实例。因此,以上的SQL写成HQL就是:

from Order as o inner join o.products as product

  现在让我们考虑另外一个从表中得到指定属性的情况。这就是最常用的select子句。这在HQL中的工作方式和SQL中一样。而在HQL中,如果只是想得到类的属性的话,select语句是最后的选择。以上的SQL可以使用select子句改成如下的HQL语句:

select product from Order as o inner join o.products as product

  以上的HQL语句将返回Order中的所有Products实例。如果要得到对象的某一个属性,可以将HQL语句写成如下的形式:

select product.name from Order as o inner join o.products as product

  如果要得到多个对象的属性,可以将HQL语句写成如下形式:

select o.id, product.name from Order as o inner join o.products as product

  接下来,我们将进入下一个议题。假设我们需要根据某些条件得到数据。那么以上所述的HQL语句将无法满足需求。为了达到这一目的,我们就要用到下面将要讨论的约束子句。
约束

  从以上可知,投影返回的是所有的数据。但在大多数时候我们并不需要这么多数据。这就需要对数据进行过滤。在HQL中过滤数据的子句和SQL一样,也是where。它的语法类似于SQL,通过where子句,可以对行进行过滤。我们可以看看下面的SQL语句:

select * from orders where id = ‘1234’

  这条查询语句返回了id等于1234的所有的字段。和这条SQL对等的是下面的HQL语句:

select o from Order o where o.id=’1234’

  从以上两条语句可以看出,它们的where子句非常相似。而它们唯一的不同是SQL操作的是记录,而HQL操作的是对象。在HQL中,除了where子句可以过滤数据外,having子句也可以做到这一点(关于having子句的详细内容我将在分组部分讨论)。投影和约束是两个基本的操作,这两个操作再加上聚合函数的话,那HQL将变得更加强大。下面我们就来讨论什么是聚合。

  聚合

  上述的查询都是将每一个记录(对象)当做一个单位,而如果使用聚合,可以将一类记录(对象)当做一个单位。然后再对每一类的记录(对象)进行一系列地操作,如对某一列取平均值、求和、统计行数等等。HQL支持以下的聚合函数:

  1. avg(…), sum(…)
  2. min(…), max(…)
  3. count(*), count(…), count(distinct…), count(all…)

  以上的聚合函数都返回数值类型。这些操作都可以在select子句中使用,如下所示:

select max(o.priceTotal) + max(p.price) from Order o join o.products p group by o.id

  以上的HQL语句返回了两个值的和:orders表中的priceTotal的最大值和products表中的price的最大值之和。我们还可以使用having子句对分组进行过滤。如我们想按id统计priceTotal小于1000的数量可按如下的HQL语句去实现:

select count(o) from Order o having o.priceTotal < 1000 group by o.id

  我们还可以将聚合函数和having子句一起使用。如我们要按products表的id统计price小于amount的平均数的产品数量,HQL语句如下:

select count(p) from Product p having p.price < avg(amount) group by p.id

  从上面的一系列的HQL语句可以看出,所有通过SQL实现的,都可以通过HQL来实现。

  分组

  在上一部分,已经涉及到了分组的概念。分组操作的是行的集合。它根据某一列(属性)对记录集进行分组。这一切是通过group子句实现的。如下的例子描述了group子句的一般用法。

select count(o) from Order o having o.priceTotal >= 1200 and o.priceTotal <= 3200 group by o.id

  HQL中的分组和SQL中的分组类似。总之,除了一些对SQL的特殊扩展外,其它所有的SQL功能都可以使用HQL描述。在接下来的部分,让我们举例说明如何在java中使用HQL。
 在java中使用HQL

  到现在为止,我们已经学习了HQL的基本用法。接下来我们举一个例子来说明如何在Java中使用HQL。下面的例子只给出了主要的部分,由于本文只是讨论HQL的用法,因此,关于Hibernate的一些设置和在main()函数中调用Hibernate的部分并未给出,读者可以参考相关的文当。现在让我们看看下面的例子。

  下面是必须引用的包
 
import java.util.List;
import org.hibernate.*;
import org.hibernate.cfg.*
import com.Order;

  下面是类的声明

public class MyOrder 
{
… …
}

  下面让我们来实现MyOrder类的构造函数

public class MyOrder
{
SessionFactory sf;

public MyOrder()
{
Configuration cfg = new Configuration().addClass(Order.class);
sf = cfg.buildSessionFactory();
}
… …
}

  下面的getOrder函数根据priceTotal的区间值返回Order对象。

public class MyOrder 
{
…. ….
public Order getOrder(String lower, String upper)
{
// 打开一个会话
Session sess = sf.openSession();
// HQL语句 
String query = "select o from o "
+ "Order as o join o.products as p "
+ "where o.priceTotal > :priceTotalLower" 
+ "and o.priceTotal< :priceTotalUpper"; 

Query q = sess.createQuery(query);
// 将两个参数传入HQL中
q.setDouble("priceTotalLower", Double.parseDouble(lower));
q.setDouble("priceTotalUpper", Double.parseDouble(upper));

List list = q.list();

Order o=(Order)list.iterator.next();

return o;

}
… …
}

  下面的main函数将测试MyOrder类

public class MyOrder
{
… …
public static void main(String args[])
{
Order o=MyOrder().getOrder(“100”, “300”); 
System.out.println(“id=”+ o.id);
… …
}
}

  小结

  上述的代码演示了如何在Java中使用HQL,但HQL还有两点需要注意一下:

  1. HQL并不区分字母的大小写,但在HQL中的Java类和属性名必须和实际的类和属性名一致。如SELECT和select之间可以互换,但Order和order却代表不同的含义。

  2. 如果HQL中引用的类未被导入,在HQL中必须引用具体的包。如本例中,如果com.Order未被导入,在HQL中必须将Order写成com.Order。 

分享到:
评论

相关推荐

    HQL学习大全.rar

    7. **HQL专题.docx**:可能是针对HQL的一些特定主题或问题的深度解析,如性能优化、动态查询等。 通过这些文档,学习者可以系统地从入门到精通,掌握HQL的全部知识,从而更好地利用Hibernate进行数据库操作。对于...

    浪磬J2EE第一期 Hibernate专题 第六讲 检索方式

    《浪磬J2EE第一期 Hibernate专题 第六讲 检索方式》 在J2EE开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。本讲主要聚焦于Hibernate的检索方式,通过深入探讨和实践,我们将...

    专题资料(2021-2022年)JavaEE轻量级解决方案S2SH试卷A和标准答案1.doc

    【Java EE轻量级解决方案S2SH】是一个专注于Java企业级开发的专题,S2SH通常指的是Struts2、Spring和Hibernate三个框架的整合。这个试卷涵盖了这些框架的基础知识和核心概念。 1. **MVC模式**:MVC(Model-View-...

    牛牛讲师Nhibernate专题讲座之NHibernate的五部曲-3

    【牛牛讲师Nhibernate专题讲座之NHibernate的五部曲-3】是一堂深入讲解NHibernate的在线课程,该课程由资深IT专家“牛牛讲师”主讲,全面覆盖了NHibernate的核心概念和实战技巧。这堂课是整个系列的第三部分,意味着...

    牛牛讲师Nhibernate专题讲座之NHibernate的五部曲-4

    【牛牛讲师Nhibernate专题讲座之NHibernate的五部曲-4】是一堂深入讲解NHibernate的在线课程,该课程由资深讲师牛牛主讲,旨在帮助开发者全面掌握这款强大的ORM(对象关系映射)框架。在这一部分中,牛牛讲师将围绕...

    [VIP][强化]J2EE第一期 Hibernate专题 第一讲 Hibernate简介源码

    总结来说,"J2EE第一期 Hibernate专题 第一讲 Hibernate简介源码"的学习内容涵盖了J2EE环境下使用Hibernate进行数据库操作的基本知识,包括Hibernate的核心概念、工作流程以及源码实践。通过深入理解并实践这些知识...

    Java面试题专题之SSH框架_ssm框架面试题.docx

    Hibernate提供HQL(Hibernate Query Language)和Criteria API进行数据库查询,它们比SQL更加面向对象。 **SSM框架组合** SSM是Spring、SpringMVC和MyBatis的组合,MyBatis是另一种轻量级ORM框架,与Hibernate...

    Java后端资料,MyBatis面试专题

    Hibernate则通过HQL或Criteria API实现对象关系映射,简化SQL操作。 - MyBatis轻量级,配置简单;Hibernate功能强大,适用于企业级应用,但可能带来性能开销。 - MyBatis的缓存机制简单,而Hibernate的缓存机制...

    专题资料(2021-2022年)jPDL流程定义语言.doc

    - 在`tns:on`标签中,可以定义事件监听器,例如触发计时器、执行HQL查询、SQL查询、Java代码、脚本或发送邮件。这些监听器提供了扩展流程行为的能力。 4. **用户代码(User Code)** - 在JPDL中,许多标签允许...

    Java企业应用框架技术培训

    5. **Hibernate**:讲解Hibernate的核心原理,对象查询,HQL,对象关系映射,并通过实际案例加深理解。 6. **iBatis框架**:对比Hibernate,学习iBatis的使用场景和技术专题。 7. **Spring框架**:深入理解Spring的...

    黑马程序员 hibernate 2016版讲义和笔记(4天全)

    本资料集是黑马程序员2016年推出的Hibernate专题课程的讲义和笔记,涵盖了4天的全面学习内容。以下将详细解析其中涉及的关键知识点。 1. Hibernate概述:首先,你需要了解Hibernate的基本概念,它是一种什么样的...

    SSH经典入门

    SSH经典入门,这是一个针对Java开发者的专题,涵盖了Spring、Hibernate和Struts三个核心框架的入门教程。这三大框架是Java企业级应用开发中非常重要的工具,它们分别在不同层面上解决了应用程序的诸多问题,帮助...

    hibernate-release-4.3.5.Final jar包

    在这个专题中,我们将深入探讨Hibernate 4.3.5.Final版本,它是Hibernate发展历史中的一个重要里程碑,为开发人员提供了强大的数据持久化功能。 一、Hibernate概述 Hibernate 是Java领域中最流行的ORM框架之一,它...

    hibernate-3.2.1.jar.zip

    在这个专题中,我们将聚焦于Hibernate 3.2.1版本,探讨其在项目框架中的集成及其核心功能。 首先,`hibernate-3.2.1.jar`是Hibernate 3.2.1的核心库文件,包含了Hibernate框架的主要类和接口,使得开发人员能够通过...

    Summer of Nhibernate Session

    《Summer of NHibernate Session》是针对NHibernate框架深入学习的一个专题系列,旨在帮助开发者更好地理解和掌握这个强大的ORM(对象关系映射)工具。NHibernate是一个流行且功能丰富的.NET框架,用于简化数据库...

    TreeViewT

    4. **查询数据**:使用Hibernate的Session接口来执行HQL(Hibernate Query Language)或SQL查询,获取数据库中的数据。这可能涉及递归查询,以获取整个树结构。 5. **构建树结构**:将查询结果转换为树节点对象,...

    java培训-Hibernate

    Java培训-Hibernate是针对Java开发人员的一个专题,主要聚焦于使用Hibernate这个强大的对象关系映射(ORM)框架来简化数据库操作。Hibernate允许开发者用面向对象的方式处理数据,从而避免了传统JDBC操作带来的繁琐...

    ssh框架客户关系系统

    在实践中,开发者需要学习如何配置这三个框架,编写Action类、Service接口及实现、DAO层以及视图层的JSP页面,同时还需要理解如何使用Hibernate的HQL语言进行数据库查询,以及Spring如何管理Bean和处理事务。...

    精通SSH(Struts+Spring+hibernate)

    《精通SSH(Struts+Spring+Hibernate)》是一个深入学习J2EE开发的专题,涵盖了三个核心的开源框架:Struts、Spring和Hibernate。这三大框架是构建企业级Java应用程序的基石,它们各自解决了Web开发中的不同问题,并...

Global site tag (gtag.js) - Google Analytics