ITEEDU

10.8. 表达式(Expressions)

where子句允许出现的表达式包括了你在SQL中可以使用的大多数情况:

  • 数学操作+, -, *, /

  • 真假比较操作 =, >=, <=, <>, !=, like

  • 逻辑操作 and, or, not

  • 字符串连接 ||

  • SQL标量( scalar)函数,例如 upper() 和 lower()

  • 没有前缀的 ( )表示分组

  • in, between, is null

  • JDBC 传入参数?

  • 命名参数 :name, :start_date, :x1

  • SQL 文字 'foo', 69, '1970-01-01 10:00:01.0'

  • Java的public static final常量 比如 Color.TABBY

in 和 between 可以如下例一样使用:

from eg.DomesticCat cat where cat.name between 'A' and 'B'

from eg.DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )

其否定形式为

from eg.DomesticCat cat where cat.name not between 'A' and 'B'

from eg.DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )

类似的,is null和is not null可以用来测试null值。

通过在Hibernate配置中声明HQL查询的替换方式,Boolean也是很容易在表达式中使用的:

<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
    )