1. 聚集函数
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
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.mateselect cat, mate from Cat cat, Cat mate where cat.mate = mate特殊属性(小写)
id
可以用来表示一个对象的唯一的标识符。(你也可以使用该对象的属性名。)from Cat as cat where cat.id = 123 from Cat as cat where cat.mate.id = 69第二个查询是有效的。此时不需要进行表连接!
同样也可以使用复合标识符。比如
Person
类有一个复合标识符,它由country
属性 与medicareNumber
属性组成。from bank.Person person where person.id.country = 'AU' and person.id.medicareNumber = 123456from bank.Account account where account.owner.id.country = 'AU' and account.owner.id.medicareNumber = 123456第二个查询也不需要进行表连接。
同样的,特殊属性
class
在进行多态持久化的情况下被用来存取一个实例的鉴别值(discriminator value)。 一个嵌入到where子句中的Java类的名字将被转换为该类的鉴别值。from Cat cat where cat.class = DomesticCat你也可以声明一个属性的类型是组件或者复合用户类型(以及由组件构成的组件等等)。永远不要尝试使用以组件类型来结尾的路径表达式(path-expression) (与此相反,你应当使用组件的一个属性来结尾)。 举例来说,如果
store.owner
含有一个包含了组件的实体address
store.owner.address.city // 正确 store.owner.address // 错误!一个“任意”类型有两个特殊的属性
id
和class
, 来允许我们按照下面的方式表达一个连接(AuditLog.item
是一个属性,该属性被映射为<any>
)。from AuditLog log, Payment payment where log.item.class = 'Payment' and log.item.id = payment.id注意,在上面的查询与句中,
log.item.class
和payment.class
将涉及到完全不同的数据库中的列。查询返回的列表(list)可以按照一个返回的类或组件(components)中的任何属性(property)进行排序:
from DomesticCat cat order by cat.name asc, cat.weight desc, cat.birthdate可选的
asc
或desc
关键字指明了按照升序或降序进行排序.一个返回聚集值(aggregate values)的查询可以按照一个返回的类或组件(components)中的任何属性(property)进行分组:
select cat.color, sum(cat.weight), count(cat) from Cat cat group by cat.colorselect foo.id, avg(name), max(name) from Foo foo join foo.names name group by foo.id
having
子句在这里也允许使用.select cat.color, sum(cat.weight), count(cat) from Cat cat group by cat.color having cat.color in (eg.Color.TABBY, eg.Color.BLACK)如果底层的数据库支持的话(例如不能在MySQL中使用),SQL的一般函数与聚集函数也可以出现 在
having
与order by
子句中。select cat from Cat cat join cat.kittens kitten group by cat.id, cat.name, cat.other, cat.properties having avg(kitten.weight) > 100 order by count(kitten) asc, sum(kitten.weight) desc注意
group by
子句与order by
子句中都不能包含算术表达式(arithmetic expressions). 也要注意Hibernate目前不会扩展group的实体,因此你不能写group by cat
,除非cat
的所有属性都不是聚集的(non-aggregated)。你必须明确的列出所有的非聚集属性。