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















 
 
 
 
 
 
 