`

HQL要点

阅读更多

    Hibernate拥有一种功能非常强大的查询语言,这种语言被有意得与SQL非常相似,便于开发人员掌握。但不要被HQL的语法表面所迷惑,HQL完全是面向对象的,可以用来过程多态、继承、关联等关系。

    1大小写敏感(Case Sensitivity)

    HQL中的使用的Java的类名和属性名是大小写敏感的,其他的关键字都是大小写不敏感的。所以“SeLeCT”等同与“sELEct”,也等同于“SELECT”,因为它不是Java类名,也不是Java类的属性名。但Java类net.sf.hibernate.eg.FOO不等同于net.sf.hibernate.eg.Foo,同样foo.barSet也不等同于foo.BARSET。

    在本手册中,HQL中的关键字均采用小写,一些用户可能发现HQL的关键字采用大写更易读,但我们也发现,当把这些HQL嵌入Java代码中,看起来很丑陋。

    2from从句(The from clause)

    Hibernate中最简单的from查询可能是:

  1. from eg.Cat 

只是简单的返回eg.Cat类的所有实例。

在很多时候你可能需要为类设置别名(alias),因为你可能需要在查询的其他部分引用Cat。

  1. from eg.Cat as cat 

关键字as是可选的,我们也可以写成:

  1. from eg.Cat cat 

可以出现多个类,然后返回一个“笛卡儿积”或交叉连接:

  1. from Formula as form, Parameter as param 

HQL中的别名用小写字母是一个好习惯,符合Java本地变量的命名规范。

3关联和连接(Associations and joins)

我们使用别名关联实体、甚至用join来关联值的集合的元素。

  1. from eg.Cat as cat  
  2.  
  3.     inner join cat.mate as mate  
  4.  
  5.     left outer join cat.kittens as kitten  
  6.  
  7. from eg.Cat as cat left join cat.mate.kittens as kittens  
  8.  
  9. from Formula form full join form.parameter param  

支持的连接类型借鉴自ANSI SQL:

· inner join

·  left outer join

·  right outer join

· full join (不常用)

inner join, left outer join和right outer join可以简写。

  1. from eg.Cat as cat  
  2.  
  3.     join cat.mate as mate  
  4.  
  5.     left join cat.kittens as kitten  

另外,一个“fetch”连接允许使用单连接来关联或值的集合,使它们可以和父对象一起来初始化。这在使用Collection的情况下特别有用。

  1. from eg.Cat as cat  
  2.  
  3.     inner join fetch cat.mate  
  4.  
  5.     left join fetch cat.kittens  

fetch join通常不需要设置别名,因为被关联的对象不应该被用在where从句中,也不能用在其他的任何从句中。

被关联的对象不能直接在查询结果中返回,他们可以通过父对象来访问。

请注意:在目前的实现中,在查询中只能返回一个集合。另外还要注意,fetch可能不用在被scroll()和iterator()调用的查询中。最后还要注意,full join fetch和right join fetch是没有意义的。

4 select从句(The select clause)

select从句用来挑选在结果集中返回的对象和属性:

  1. select cat.mate from eg.Cat cat 

上面这个查询返回所有猫的配偶。

你也可以使用elements函数返回集合的元素。下面的查询将返回任何猫(Cat)的所有小猫(Kitten)。

  1. select elements(cat.kittens) from eg.Cat cat 

查询也可以返回任何值类型(包括Component类型的属性)的属性:

  1. select cat.name from eg.DomesticCat cat  
  2.  
  3. where cat.name like 'fri%' 
  4.  
  5. select cust.name.firstName from Customer as cust  

查询可以返回多个对象,也可以返回作为Object[]类型的数组的属性。

  1. select mother, offspr, mate.name 
  2.  
  3. from eg.DomesticCat as mother  
  4.  
  5.     inner join mother.mate as mate  
  6.  
  7.     left outer join mother.kittens as offspr  

或者作为一个实际的Java对象:

  1. select new Family(mother, mate, offspr)  
  2.  
  3. from eg.DomesticCat as mother  
  4.  
  5.     join mother.mate as mate  
  6.  
  7.     left join mother.kittens as offspr  

上面的这个查询语句假设Family类有适当的构造函数。

5 聚集函数(Aggregate functions)

查询可以使用属性的聚集函数:

  1. select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)  from eg.Cat cat 

select从句的聚集函数中可以出现集合:

select cat, count( elements(cat.kittens) )  from eg.Cat cat group by cat

支持的聚集函数有:

· avg(...), sum(...), min(...), max(...)

· count(*)

· count(...), count(distinct ...), count(all...)

distinct 和all关键字的意义与用法和SQL中相同:

  1. select distinct cat.name from eg.Cat cat  
  2.  
  3. select count(distinct cat.name), count(cat) from eg.Cat cat  

6 多态(polymorphism)

一个查询:from eg.Cat as cat,它返回的不只是Cat,也有DomesticCat(家猫)这样的子类。Hibernate可以在from从句中指定任何Java类和接口,查询将返回继承自该类和实现了该接口的所有的持久类的实例。下面的查询将返回所有持久的对象:

  1. from java.lang.Object o 

指定的接口可以被多个不同的持久类实现:

  1. from eg.Named n, eg.Named m where n.name = m.name 

注意最后2个查询将需要超过1个SQL的select,这意味着不能够按照从句指定的排列次序排列整个结果集。这也意味着你不能用Query.scroll()来调用这些查询。

7 where从句(The where clause)

where从句是你可以按照自己指定的条件更精确的返回实例:

  1. from eg.Cat as cat where cat.name='Fritz' 

复合表达式使where从句功能非常强大:

  1. from eg.Cat as cat where cat.name='Fritz'  

这个查询将被翻译成带有一个连接的SQL查询语句。

如果你写下这句查询:

  1. from eg.Foo foo where foo.bar.baz.customer.address.city is not null 

这个查询翻译成SQL语句需要4个表连接。

“=”操作符不仅可以比较属性,也可以比较实例:

  1. from eg.Cat cat, eg.Cat rival where cat.mate = rival.mate  
  2.  
  3. select cat, mate  from eg.Cat cat, eg.Cat mate  where cat.mate = mate  

一个叫id的特殊的属性被用来引用一个对象的唯一标识符,你也可以用对象的属性名。

  1. from eg.Cat as cat where cat.id = 123  
  2.  
  3. from eg.Cat as cat where cat.mate.id = 69    

这个查询要比上一个有效率,因为不需要表连接。

可以使用复合主键的属性。假设person有一个由medicareNumber和country构成的符合主键:

  1. from bank.Person person  
  2.  
  3. where person.id.country = 'AU' 
  4.  
  5. and person.id.medicareNumber = 123456  
  6.  
  7. from bank.Account account  
  8.  
  9. where account.owner.id.country = 'AU' 
  10.  
  11.     and account.owner.id.medicareNumber = 123456  

再重复一次,第二个查询效率高些。

同样,一个指定了属性的类在多态持久(polymorphic persistence)的情况下访问实体的discriminator value。

一个被嵌入到where从句中的Java类名将被翻译成它的discriminator value。

from eg.Cat cat where cat.class = eg.DomesticCat

你也可以指定组件(component)的属性和用户自己定义的合成类型(及组件的组件等等)。

永远也不要使用一个以组件的属性结尾的路径表达式。举个例子,假设store.owner是一个带有一个叫address组件的实体:

  1. store.owner.address.city    //正确  
  2.  
  3. store.owner.address        //错误!  

一个叫“any”的类型有2个特别的属性,一个是id,另一个是class,它允许我们用下面的办法进行连接(join)。AuditLog.item是一个用<  any>映射的属性:

  1. from eg.AuditLog log, eg.Payment payment  
  2.  
  3. where log.item.class = 'eg.Payment' and log.item.id = payment.id  

需要注意的是:查询中的log.item.class和payment.class将参考完全不同的数据库列。

8 表达式(Expressions)

where从句中的表达式允许你使用SQL中的很多东西:

· 数学运算符: +, -, *, /

· 二元比较运算符: =, >=, <  =, <  >, !=, like

· 逻辑操作符: and, or, not

· 字符串连接符: ||

· SQL函数,如: upper() and lower()

· 圆括号: ( )

· in, between, is null

· JDBC输入参数: ?

· 指定的参数::name, :start_date, :x1

· in和between:

  1. from eg.DomesticCat cat where cat.name between 'A' and 'B' 
  2.  
  3. from eg.DomesticCat cat where cat.name in ( 'Foo''Bar''Baz' )  

和否定形式的(negated forms):

  1. from eg.DomesticCat cat where cat.name not between 'A' and 'B' 
  2.  
  3. from eg.DomesticCat cat where cat.name not in ( 'Foo''Bar''Baz' )  

· is null和is not null

· 也可以使用特殊的属性size或size()函数来测试集合的大小:

  1. from eg.Cat cat where cat.kittens.size > 0  
  2.  
  3. from eg.Cat cat where size(cat.kittens) > 0  

·  对于有索引的集合,你可以使用特殊属性minIndex和maxIndex来引用最小索引和最大索引。同样,你也可以使用minElement和maxElement来引用基本类型的集合的minimum和maximum元素。

  1. from Calendar cal where cal.holidays.maxElement > current date 

也可以是函数的形式:

  1. from Order order where maxindex(order.items) > 100  
  2.  
  3. from Order order where minelement(order.items) > 10000  

在传递索引和元素给集合时(elements and indices函数)和传递子查询的结果集时,SQL函数any, some, all, exists, in都是被支持的:

  1. select mother from eg.Cat as mother, eg.Cat as kit  
  2.  
  3. where kit in elements(foo.kittens)  
  4.  
  5. select p from eg.NameList list, eg.Person p  
  6.  
  7. where p.name = some elements(list.names)  
  8.  
  9. from eg.Cat cat where exists elements(cat.kittens)  
  10.  
  11. from eg.Player p where 3 > all elements(p.scores)  
  12.  
  13. from eg.Show show where 'fizard' in indices(show.acts)  

请注意:size, elements, indices, minIndex, maxIndex, minElement, maxElement在使用时有一些限制:

v      where从句中的in只用于数据库的子查询。

v      select从句中的in只用于elements 和indices函数。

v      带有索引的元素的collection(arrays, lists, maps)只能在where从句中通过索引引用:

  1. from Order order where order.items[0].id = 1234  
  2.  
  3. select person from Person person, Calendar calendar  
  4.  
  5. where calendar.holidays['national day'] = person.birthDay  
  6.  
  7.     and person.nationality.calendar = calendar  
  8.  
  9. select item from Item item, Order order 
  10.  
  11. where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11  
  12.  
  13. select item from Item item, Order order 
  14.  
  15. where order.items[ maxindex(order.items) ] = item and order.id = 11  

表达式中的[]的内部可以是一个算术表达式:

  1. select item from Item item, Order order 
  2.  
  3. where order.items[ size(order.items) - 1 ] = item  

HQL为one-to-many关联和值的集合提供了内置的index()函数:

  1. select item, index(item) from Order order 
  2.  
  3.     join order.items item  
  4.  
  5. where index(item) <  5  

被一些特定数据库支持的SQL函数可以被使用:

  1. from eg.DomesticCat cat where upper(cat.namelike 'FRI%' 

如果你还不相信上面的一切,那么想想更长的和更短的可读的查询吧:

  1. select cust  
  2. from Product prod,  
  3.     Store store  
  4.     inner join store.customers cust  
  5. where prod.name = 'widget' 
  6.     and store.location.name in ( 'Melbourne''Sydney' )  
  7.     and prod = all elements(cust.currentOrder.lineItems) 

提示:something like

  1. SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order  
  2. FROM customers cust,  
  3.     stores store,  
  4.     locations loc,  
  5.     store_customers sc,  
  6.     product prod  
  7. WHERE prod.name = 'widget' 
  8.     AND store.loc_id = loc.id  
  9.     AND loc.name IN ( 'Melbourne''Sydney' )  
  10.     AND sc.store_id = store.id  
  11.     AND sc.cust_id = cust.id  
  12. <spa
    分享到:
    评论

相关推荐

    HibernateHql综合测试小程序

    本文将详细解析该测试程序的要点,以及如何在MyEclipse环境中运行和测试。 首先,HQL是Hibernate提供的SQL的面向对象版本,它允许开发者使用对象而不是表格来编写查询。HQL支持基本的查询操作,如选择、投影、连接...

    Hql语句注意事项总结

    以下是对这些要点的详细说明: 1. **在Hql中使用`group by`的问题** - **统计函数与分组**:在Hql中,`group by`语句用于对数据进行分组,常与聚合函数如`sum()`、`count()`、`max()`等结合使用。例如,你可以选择...

    Java Hibernate中使用HQL语句进行数据库查询的要点解析

    在使用HQL进行数据库查询时,有以下几个关键要点需要理解: 1. **实体对象查询**: HQL查询基于实体对象,这意味着我们在编写查询时使用类名和类的属性。例如,如果我们有一个`Student`类,我们可以编写如下的HQL...

    Hive开发规范及要点

    它提供了一个SQL-like的查询语言,称为HQL(Hive Query Language),使得用户可以使用类似SQL的语句来查询和管理数据。在Hive开发中,遵循一定的规范和要点非常重要,以下是Hive开发规范及要点: 一、基本操作 1. ...

    hibernate和spring技术难点及其要点总结

    【标题】:“hibernate和spring技术难点及其要点总结” 【描述】:“hibernate和spring技术难点及其要点总结” 本文将深入探讨Hibernate和Spring框架在Java开发中的关键概念、应用场景以及技术难点。首先,我们来...

    hibernate配置要点详谈

    ### Hibernate配置要点详谈 #### 一、配置文件与配置方式 在Hibernate中,有两种主要的配置文件形式:`hibernate.cfg.xml` 和 `hibernate.properties`。 1. **`hibernate.cfg.xml`**: - 这种配置文件通常包含...

    java之hibernate和spring技术难点及其要点总结

    ### Java之Hibernate和Spring技术难点及其要点总结 #### Hibernate与Spring技术概述 在Java开发领域,Hibernate和Spring作为两个非常重要的框架,对于提高应用程序的开发效率、降低维护成本具有不可替代的作用。...

    达内Java知识要点part3

    【达内Java知识要点part3】的压缩包包含了一些核心的Java Web开发技术,包括Spring、Hibernate、AJAX与jQuery、JSP以及Struts2。这些框架和技术在现代企业级应用开发中扮演着至关重要的角色。以下是关于这些知识点的...

    Hibernate程序性能优化的考虑要点

    ### Hibernate程序性能优化的考虑要点 在开发基于Hibernate框架的应用时,性能优化是至关重要的环节。Hibernate作为一款优秀的对象关系映射(ORM)工具,它能够简化Java应用程序与数据库之间的交互,但不当的配置和...

    Spring Hibernate 整合要点之JPA

    下面我们将详细讲解整合Spring、Hibernate与JPA的要点。 1. **依赖包** 在整合Spring和Hibernate的JPA之前,首先需要确保引入了正确的依赖包。这包括Spring的核心库、Hibernate的Core库以及JPA相关的库。如`spring...

    Hibernate复习题1含答案要点.doc

    - **Criteria查询**是Hibernate提供的另一种查询方式,除了传统的HQL(Hibernate Query Language),Criteria API允许以面向对象的方式构建查询,更符合Java的编程习惯。创建Criteria对象的正确方式是`Criteria c = ...

    基于SSH框架实现学员关系管理系统(CRM)【100012800】

    通过Struts2、Hibernate、spring框架整合做的一个CRM系统,整体开发比较简单,就是细节的地方处理还是要花费...涉及的技术要点就是通过HQL来进行数据的增删改查、部门-职务级联、分页、通过struts进行文件上传下载等。

    java最新面试宝典

    - Criteria API与HQL(Hibernate Query Language)的区别。 - 一级缓存与二级缓存的管理。 - **面试考察要点:** - Hibernate与其他持久层框架的对比。 - 如何利用Hibernate简化数据库操作。 **补充☆9.6 ...

    SSH整合要点

    - **HQL(Hibernate Query Language)**:面向对象的查询语言,类似SQL但更适应ORM环境。 - **第二级缓存**:提高数据访问效率,可配置缓存插件如Ehcache。 4. **SSH整合**: - **Spring管理Struts2 Action**:...

    hive基础知识复习笔记.zip

    Hive是Apache软件基金会开发的一个数据仓库工具,主要用于处理和管理大数据。它允许用户使用SQL(称为HQL,Hive Query Language)查询分布式存储的...掌握这些要点,将有助于理解Hive在大数据处理中的作用和使用方式。

    Hibernate多表查询.txt

    ### 实践要点与注意事项 - **理解关联映射**:在多表查询中,正确理解和设置实体间的关联关系至关重要。这包括一对一、一对多和多对多等多种类型,不同的关联关系会影响查询语句的编写和执行效率。 - **优化查询...

    Java语言基础下载

    第三十六章:HQL介绍 706 学习目标 706 HQL的出现 707 进入HQL世界 707 聚合 708 分组 709 在Java中使用HQL 709 内容总结 712 独立实践 712 第三十七章 Spring介绍 713 学习目标 713 Spring简介 714 IOC控制反转 714...

    hibernate3.6 文档(pdf 格式)

    - **结论**:总结双向一对多关系的映射要点。 #### 二十五、示例:博客应用程序 - **持久化类**:展示博客应用程序中涉及的持久化类。 - **Hibernate 映射**:提供博客应用程序的 Hibernate 映射示例。 - **...

    hibernate 的各种操作

    - `createQuery("from Users where userid=:id")`:创建 HQL 查询语句,其中 `:id` 是参数占位符。 - `setString("id", id)`:设置参数值。 - `queryList.get(0)`:获取查询结果列表中的第一个对象。 #### 5. ...

    Java Persistence With Hibernate(2008)

    - **HQL与Criteria API:** Hibernate提供了两种主要的查询方式:HQL(Hibernate Query Language)和Criteria API。HQL类似于SQL,但更加面向对象;Criteria API则提供了一种更灵活的方式来构建复杂的查询条件。 - *...

Global site tag (gtag.js) - Google Analytics