`
ZhouGang库鲁卡
  • 浏览: 28803 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

(转)HQL语法

 
阅读更多
 
 

Hibernate

配备了一种非常强大的查询语言,这种语言看上去很像SQ。但是不要被语法结构上的相似所迷惑,HQL是非常有意识的被设计为完全面向对象的查询,它可以理解如继承、多态和关联之类的概念。

 

 

1.1. 

大小写敏感性问题

 

除了Java类与属性的名称外,查询语句对大小写并不敏感。所以SeLeCT 与sELEct 以及SELECT 是相同的,但是

 org.hibernate.eg.FOO 并不等价于org.hibernate.eg.Foo 并且foo.barSet 也不等价于foo.BARSET。

 

 

本手册中的

HQL

关键字将使用小写字母

很多用户发现使用完全大写的关键字会使查询语

 

的可读性更强

但我们发现,

当把查询语句嵌入到

Java

语句中的时候使用大写关键字比

较难看。

 

 

 

14.2. from

子句

 

Hibernate

中最简单的查询语句的形式如下:

 

 

 

from eg.Cat 

该子句简单的返回

eg.Cat

类的所有实例。

 

通常我们不需要使用类的全限定名

因为

 

auto-import

(自动引入)

 

是缺省的情况。

 

所以我们几乎只使用如下的简单写法:

 

 

 

from Cat 

大多数情况下

你需要指定一个别名

原因是你可能需要

 

在查询语句的其它部分引用到

Cat 

 

 

from Cat as cat 

这个语句把别名

cat

指定给类

Cat 

的实例

这样我们就可以在随后的查询中使用此别名了。

 

关键字

as 

是可选的,我们也可以这样写

 

 

from Cat cat 

子句中可以同时出现多个类

其查询结果是产生一个笛卡儿积或产生跨表的连接。

 

 

 

from Formula, Parameter 

from Formula as form, Parameter as param 

查询语句中别名的开头部分小写被认为是实践中的好习惯,

 

这样做与

Java

变量的命名标

准保持了一致

 

(

比如,

domesticCat)

 

 

 

14.3. 

关联

(Association)

与连接

(Join) 

我们也可以为相关联的实体甚至是对一个集合中的全部元素指定一个别名

这时要使用关

键字

join

 

 

 

 

from Cat as cat 

 

  

 inner join cat.mate as mate 

  

 left outer join cat.kittens as kitten 

from 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 Cat as cat 

 

  

 join cat.mate as mate 

  

 left join cat.kittens as kitten 

通过

HQL

with

关键字,你可以提供额外的

join

条件。

 

 

 

from Cat as cat 

 

  

 left join cat.kittens as kitten 

 

  

  

  

 with kitten.bodyWeight > 10.0 

还有,

一个

"fetch"

连接允许仅仅使用一个选择语句就将相关联的对象或一组值的集合随着他

们的父对象的初始化而被初始化,

这种方法在使用到集合的情况下尤其有用,

对于关联和集

合来说,它有效的代替了映射文件中的外联接

 

与延迟声明(

lazy 

declarations

查看

 

 

19.1 

 

 

抓取策略

(Fetching strategies) 

 

以获得等多的信息。

 

 

 

from Cat as cat 

 

  

 inner join fetch cat.mate 

  

 left join fetch cat.kittens 

一个

fetch

连接通常不需要被指定别名

因为相关联的对象不应当被用在

 

where 

子句

 

(

其它任何子句

)

中。同时,相关联的对象

 

并不在查询的结果中直接返回,但可以通过他们的

父对象来访问到他们。

 

 

 

from Cat as cat 

 

  

 inner join fetch cat.mate 

  

 left join fetch cat.kittens child 

  

 left join fetch child.kittens 

假若使用

iterate()

来调用查询,

请注意

fetch

构造是不能使用的

(scroll() 

可以使用

)

fetch

不应该与

setMaxResults() 

setFirstResult()

共用,

这是因为这些操作是基于结果集的,

在预先抓取集合类时可能包含重复的数据,也就是说无法预先知道精确的行数。

fetch

还不

 

能与独立的

 

with

条件一起使用。通过在一次查询中

fetch

多个集合,可以制造出笛卡尔积,

因此请多加注意。对

bag

映射来说,同时

join fetch

多个集合角色可能在某些情况下给出并

非预期的结果,也请小心。最后注意,使用

full join fetch 

 

right join fetch

是没有意义的。

 

 

 

如果你使用属性级别的延迟获取(

lazy fetching

(这是通过重新编写字节码实现的)

,可以

使用

 

fetch all properties 

来强制

Hibernate

立即取得那些原本需要延迟加载的属性

(在第一

个查询中)

 

 

 

from Document fetch all properties order by name 

from Document doc fetch all properties where lower(doc.name) like '%cats%' 

14.4. join 

语法的形式

 

HQL

支持两种关联

join

的形式:

implicit(

隐式

explicit

(显式)

 

 

 

上一节中给出的查询都是使用

explicit(

显式

)

形式的,其中

form

子句中明确给出了

join

关键

字。这是建议使用的方式。

 

 

 

implicit

(隐式)形式不使用

join

关键字。关联使用

"

点号

"

来进行“引用”

implicit join

可以

在任何

HQL

子句中出现

.implicit join

在最终的

SQL

语句中以

inner join

的方式出现。

 

 

 

from Cat as cat where cat.mate.name like '%s%' 

14.5. select

子句

 

select 

子句选择将哪些对象与属性返

 

回到查询结果集中

考虑如下情况

 

 

select mate 

 

from Cat as cat 

 

  

 inner join cat.mate as mate 

该语句将选择

mates of other Cats

(其他猫的配偶)

 

实际上

你可以更简洁的用以下的查

询语句表达相同的含义

 

 

select cat.mate from Cat cat 

查询语句可以返回值为任何类型的属性,包括返回类型为某种组件

(Component)

的属性

 

 

select cat.name from DomesticCat cat 

where cat.name like 'fri%' 

select cust.name.firstName from Customer as cust 

查询语句可以返回多个对象和(或)属性,存放在

 

Object[]

队列中

 

 

select mother, offspr, mate.name 

 

from DomesticCat as mother 

  

 inner join mother.mate as mate 

  

 left outer join mother.kittens as offspr 

或存放在一个

List

对象中

 

 

select new list(mother, offspr, mate.name) 

 

from DomesticCat as mother 

  

 inner join mother.mate as mate 

  

 left outer join mother.kittens as offspr 

也可能直接返回一个实际的类型安全的

Java

对象

 

 

select new Family(mother, mate, offspr) 

from DomesticCat as mother 

  

 join mother.mate as mate 

  

 left join mother.kittens as offspr 

假设类

Family

有一个合适的构造函数

 

 

你可以使用关键字

as

给“被选择了的表达式”指派别名

 

 

select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n 

from Cat cat 

这种做法在与子句

select new map

一起使用时最有用

 

 

select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n ) 

from Cat cat 

该查询返回了一个

Map

的对象,内容是别名与被选择的值组成的名

-

值映射。

 

 

 

14.6. 

聚集函数

 

HQL

查询甚至可以返回作用于属性之上的聚集函数的计算结果

 

 

select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) 

from Cat cat 

受支持的聚集函数如下:

 

 

 

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

 

 

count(*) 

 

 

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

 

 

你可以在选择子句中使用数学操作符、连接以及经过验证的

SQL

函数:

 

 

 

select cat.weight + sum(kitten.weight) 

 

from Cat cat 

 

  

 join cat.kittens kitten 

group by cat.id, cat.weight 

select firstName||' '||initial||' '||upper(lastName) from Person 

关键字

distinct

all 

也可以使用,它们具有与

SQL

相同的语义

 

 

select distinct cat.name from Cat cat 

 

 

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

14.7. 

多态查询

 

一个如下的查询语句

 

 

from Cat as cat 

不仅返回

Cat

类的实例

也同时返回子类

 

DomesticCat

的实例

Hibernate 

可以在

from

句中指定任何

 

Java 

类或接口

查询会返回继承了该类的所有持久化子类

 

的实例或返回声

明了该接口的所有持久化类的实例。下面的查询语句返回所有的被持久化的对象:

 

 

 

from java.lang.Object o 

接口

Named 

可能被各种各样的持久化类声明:

 

 

 

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

注意,最后的两个查询将需要超过一个的

SQL 

SELECT.

这表明

order 

by

子句

 

没有对整个

结果集进行正确的排序

. (

这也说明你不能对这样的查询使用

Query.scroll()

方法

.) 

 

 

14.8. where

子句

 

where

子句允许你将返回的实例列表的范围缩小

如果没有指定别名,

你可以使用属性名来

直接引用属性

 

 

from Cat where name='Fritz' 

如果指派了别名,需要使用完整的属性名

 

 

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

返回名为(属性

name

等于)

'Fritz'

Cat

类的实例。

 

 

 

select foo 

 

from Foo foo, Bar bar 

where foo.startDate = bar.date 

将返回所有满足下面条件的

Foo

类的实例:

 

存在如下的

bar

的一个实例,其

date

属性等

 

Foo

startDate

属性。

 

复合路径表达式使得

where

子句非常的强大,考虑如下情况:

 

 

 

from Cat cat where cat.mate.name is not null 

该查询将被翻译成为一个含有表连接(内连接)的

SQL

查询。如果你打算写像这样的查询

语句

 

 

 

from Foo foo 

  

where foo.bar.baz.customer.address.city is not null 

SQL

中,你为达此目的将需要进行一个四表连接的查询。

 

 

 

=

运算符不仅可以被用来比较属性的值,也可以用来比较实例:

 

 

 

from Cat cat, Cat rival where cat.mate = rival.mate 

 
 
 
 
 
 
 
 
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics