<property name="hibernate.query.substitutions">true 1, false 0</property>
在从HQL翻译成SQL的时候,关键字true和false就会被替换成1和0。
from eg.Cat cat where cat.alive = true
你可以用特殊属性size来测试一个集合的长度,或者用特殊的size()函数也可以。
from eg.Cat cat where cat.kittens.size > 0
from eg.Cat cat where size(cat.kittens) > 0
对于排序集合,你可以用minIndex和maxIndex来获取其最大索引值和最小索引值。类似的,minElement 和maxElement 可以用来获取集合中最小和最大的元素,前提是必须是基本类型的集合。
from Calendar cal where cal.holidays.maxElement > current date
也有函数的形式(和上面的形式不同,函数形式是大小写不敏感的):
from Order order where maxindex(order.items) > 100
from Order order where minelement(order.items) > 10000
SQL中的any, some, all, exists, in功能也是支持的,前提是必须把集合的元素或者索引集作为它们的参数(使用element和indices函数),或者使用子查询的结果作为参数。
select mother from eg.Cat as mother, eg.Cat as kit
where kit in elements(foo.kittens)
select p from eg.NameList list, eg.Person p
where p.name = some elements(list.names)
from eg.Cat cat where exists elements(cat.kittens)
from eg.Player p where 3 > all elements(p.scores)
from eg.Show show where fizard in indices(show.acts)
请注意这些设施:size,elements,indices,minIndex,maxIndex,minElement,maxElement 都有一些使用限制:
在where子句中: 只对支持子查询的数据库有效
在select子句中:只有elements和indices有效
有序的集合(数组、list、map)的元素可以用索引来进行引用(只限于在where子句中)
from Order order where order.items[0].id = 1234
select person from Person person, Calendar calendar
where calendar.holidays[national day] = person.birthDay
and person.nationality.calendar = calendar
select item from Item item, Order order
where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11
select item from Item item, Order order
where order.items[ maxindex(order.items) ] = item and order.id = 11
[]中的表达式允许是另一个数学表达式。
select item from Item item, Order order
where order.items[ size(order.items) - 1 ] = item
HQL也对一对多关联或者值集合提供内置的index()函数。
select item, index(item) from Order order
join order.items item
where index(item) < 5
底层数据库支持的标量SQL函数也可以使用
from eg.DomesticCat cat where upper(cat.name) like FRI%
假如以上的这些还没有让你信服的话,请想象一下下面的查询假若用SQL来写,会变得多么长,多么不可读:
select cust
from Product prod,
Store store
inner join store.customers cust
where prod.name = widget
and store.location.name in ( Melbourne, Sydney )
and prod = all elements(cust.currentOrder.lineItems)
提示:对应的SQL语句可能是这样的
SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order
FROM customers cust,
stores store,
locations loc,
store_customers sc,
product prod
WHERE prod.name = widget
AND store.loc_id = loc.id
AND loc.name IN ( Melbourne, Sydney )
AND sc.store_id = store.id
AND sc.cust_id = cust.id
AND prod.id = ALL(
SELECT item.prod_id
FROM line_items item, orders o
WHERE item.order_id = o.id
AND cust.current_order = o.id
)
11.9. order by 子句
查询返回的列表可以按照任何返回的类或者组件的属性排序:
from eg.DomesticCat cat
order by cat.name asc, cat.weight desc, cat.birthdate
asc和desc是可选的,分别代表升序或者降序。
11.10. group by 子句
返回统计值的查询可以按照返回的类或者组件的任何属性排序:
select cat.color, sum(cat.weight), count(cat)
from eg.Cat cat
group by cat.color
select foo.id, avg( elements(foo.names) ), max( indices(foo.names) )
from eg.Foo foo
group by foo.id
请注意:你可以在select子句中使用elements和indices指令,即使你的数据库不支持子查询也可以。
having子句也是允许的。
select cat.color, sum(cat.weight), count(cat)
from eg.Cat cat
group by cat.color
having cat.color in (eg.Color.TABBY, eg.Color.BLACK)
在having子句中允许出现SQL函数和统计函数,当然这需要底层数据库支持才行。(比如说,MySQL就不支持)
select cat
from eg.Cat cat
join cat.kittens kitten
group by cat
having avg(kitten.weight) > 100
order by count(kitten) asc, sum(kitten.weight) desc
注意,group by子句和order by子句都不支持数学表达式。
11.11. 子查询
对于支持子查询的数据库来说,Hibernate支持在查询中嵌套子查询。子查询必须由圆括号包围(常常是在一个SQL统计函数中)。也允许关联子查询(在外部查询中作为一个别名出现的子查询)。
from eg.Cat as fatcat
where fatcat.weight > (
select avg(cat.weight) from eg.DomesticCat cat
)
from eg.DomesticCat as cat
where cat.name = some (
select name.nickName from eg.Name as name
)
from eg.Cat as cat
where not exists (
from eg.Cat as mate where mate.mate = cat
)
from eg.DomesticCat as cat
where cat.name not in (
select name.nickName from eg.Name as name
)
11.12. HQL示例
Hibernate查询可以非常强大复杂。实际上,强有力的查询语言是Hibernate的主要卖点之一。下面给出的示例与我在近期实际项目中使用的一些查询很类似。请注意你编写的查询大部分等都不会这么复杂!