兔八哥笔记14(1):Hibernate 查询语言(HQL)

类别:Java 点击:0 评论:0 推荐:

兔八哥笔记14(1):Hibernate 查询语言(HQL)

 

                     邮箱:[email protected]

 

本文翻译自Hibernate的文档第10章《Hibernate Query Language》。

 

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

 

10.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代码中,看起来很丑陋。

10.2from从句(The from clause)

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

from eg.Cat

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

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

from eg.Cat as cat

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

from eg.Cat cat

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

from Formula as form, Parameter as param

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

10.3关联和连接(Associations and joins)

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

from eg.Cat as cat

    inner join cat.mate as mate

    left outer join cat.kittens as kitten

 

from eg.Cat as cat left join cat.mate.kittens as kittens

 

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可以简写。

from eg.Cat as cat

    join cat.mate as mate

    left join cat.kittens as kitten

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

from eg.Cat as cat

    inner join fetch cat.mate

    left join fetch cat.kittens

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

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

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

10.4 select从句(The select clause)

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

select cat.mate from eg.Cat cat

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

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

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

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

select cat.name from eg.DomesticCat cat

where cat.name like 'fri%'

select cust.name.firstName from Customer as cust

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

select mother, offspr, mate.name

from eg.DomesticCat as mother

    inner join mother.mate as mate

    left outer join mother.kittens as offspr

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

select new Family(mother, mate, offspr)

from eg.DomesticCat as mother

    join mother.mate as mate

    left join mother.kittens as offspr

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

10.5 聚集函数(Aggregate functions)

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

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中相同:

select distinct cat.name from eg.Cat cat

 

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

 

10.6 多态(polymorphism)

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

from java.lang.Object o

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

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

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

本文地址:http://com.8s8s.com/it/it16840.htm