簡(jiǎn)述Hibernate三種查詢(xún)的應(yīng)用
Hibernate配備了一種非常強(qiáng)大的Hibernate查詢(xún)語(yǔ)言,這種語(yǔ)言看上去很像SQL。本文主要介紹where子句、order by子句、group by子句。但是不要被語(yǔ)法結(jié)構(gòu) 上的相似所迷惑,HQL是非常有意識(shí)的被設(shè)計(jì)為完全面向?qū)ο蟮牟樵?xún),它可以理解如繼承、多態(tài) 和關(guān)聯(lián)之類(lèi)的概念。
1. where子句
Hibernate查詢(xún)語(yǔ)言where子句允許你將返回的實(shí)例列表的范圍縮小. 如果沒(méi)有指定別名,你可以使用屬性名來(lái)直接引用屬性:
- from Cat where name='Fritz'
如果指派了別名,需要使用完整的屬性名:
- from Cat as cat where cat.name='Fritz'
返回名為(屬性name等于)'Fritz'的Cat類(lèi)的實(shí)例。
- select foo
- from Foo foo, Bar bar
- where foo.startDate = bar.date
將返回所有滿足下面條件的Foo類(lèi)的實(shí)例: 存在如下的bar的一個(gè)實(shí)例,其date屬性等于 Foo的startDate屬性。 復(fù)合路徑表達(dá)式使得where子句非常的強(qiáng)大,考慮如下情況:
- from Cat cat where cat.mate.name is not null
該Hibernate查詢(xún)將被翻譯成為一個(gè)含有表連接(內(nèi)連接)的SQL查詢(xún)。如果你打算寫(xiě)像這樣的查詢(xún)語(yǔ)句
- from Foo foo
- where foo.bar.baz.customer.address.city is not null
在SQL中,你為達(dá)此目的將需要進(jìn)行一個(gè)四表連接的查詢(xún)。
=運(yùn)算符不僅可以被用來(lái)比較屬性的值,也可以用來(lái)比較實(shí)例:
- from Cat cat, Cat rival where cat.mate = rival.mate
- select cat, mate
- from Cat cat, Cat mate
- where cat.mate = mate
特殊屬性(小寫(xiě))id可以用來(lái)表示一個(gè)對(duì)象的唯一的標(biāo)識(shí)符。(你也可以使用該對(duì)象的屬性名。)
- from Cat as cat where cat.id = 123
- from Cat as cat where cat.mate.id = 69
第二個(gè)查詢(xún)是有效的。此時(shí)不需要進(jìn)行表連接!
同樣也可以使用復(fù)合標(biāo)識(shí)符。比如Person類(lèi)有一個(gè)復(fù)合標(biāo)識(shí)符,它由country屬性 與medicareNumber屬性組成。
- from bank.Person person
- where person.id.country = 'AU'
- and person.id.medicareNumber = 123456
- from bank.Account account
- where account.owner.id.country = 'AU'
- and account.owner.id.medicareNumber = 123456
第二個(gè)查詢(xún)也不需要進(jìn)行表連接。
同樣的,特殊屬性class在進(jìn)行多態(tài)持久化的情況下被用來(lái)存取一個(gè)實(shí)例的鑒別值(discriminator value)。 一個(gè)嵌入到where子句中的Java類(lèi)的名字將被轉(zhuǎn)換為該類(lèi)的鑒別值。
- from Cat cat where cat.class = DomesticCat
你也可以聲明一個(gè)屬性的類(lèi)型是組件或者復(fù)合用戶(hù)類(lèi)型(以及由組件構(gòu)成的組件等等)。永遠(yuǎn)不要嘗試使用以組件類(lèi)型來(lái)結(jié)尾的路徑表達(dá)式(path-expression) (與此相反,你應(yīng)當(dāng)使用組件的一個(gè)屬性來(lái)結(jié)尾)。 舉例來(lái)說(shuō),如果store.owner含有一個(gè)包含了組件的實(shí)體address
- store.owner.address.city // 正確
- store.owner.address // 錯(cuò)誤!
一個(gè)“任意”類(lèi)型有兩個(gè)特殊的屬性id和class, 來(lái)允許我們按照下面的方式表達(dá)一個(gè)連接(AuditLog.item 是一個(gè)屬性,該屬性被映射為
- from AuditLog log, Payment payment
- where log.item.class = 'Payment' and log.item.id = payment.id
注意,在上面的查詢(xún)與句中,log.item.class 和 payment.class 將涉及到完全不同的數(shù)據(jù)庫(kù)中的列。
2. order by子句
查詢(xún)返回的列表(list)可以按照一個(gè)返回的類(lèi)或組件(components)中的任何屬性(property)進(jìn)行排序:
- from DomesticCat cat
- order by cat.name asc, cat.weight desc, cat.birthdate
可選的asc或desc關(guān)鍵字指明了按照升序或降序進(jìn)行排序.
- select cat.color, sum(cat.weight), count(cat)
- from Cat cat
- group by cat.color
- select foo.id, avg(name), max(name)
- from Foo foo join foo.names name
- group by foo.id
3. group by子句
一個(gè)返回聚集值(aggregate values)的查詢(xún)可以按照一個(gè)返回的類(lèi)或組件(components)中的任何屬性(property)進(jìn)行分組:
- 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)
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)
如果底層的數(shù)據(jù)庫(kù)支持的話(例如不能在MySQL中使用),SQL的一般函數(shù)與聚集函數(shù)也可以出現(xiàn) 在having與order by 子句中。
- select cat
- from 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子句中都不能包含算術(shù)表達(dá)式(arithmetic expressions).
【編輯推薦】