簡述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的一個(gè)實(shí)例,其date屬性等于 Foo的startDate屬性。 復(fù)合路徑表達(dá)式使得where子句非常的強(qiáng)大,考慮如下情況:
- from Cat cat where cat.mate.name is not null
該Hibernate查詢將被翻譯成為一個(gè)含有表連接(內(nèi)連接)的SQL查詢。如果你打算寫像這樣的查詢語句
- from Foo foo
- where foo.bar.baz.customer.address.city is not null
在SQL中,你為達(dá)此目的將需要進(jìn)行一個(gè)四表連接的查詢。
=運(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可以用來表示一個(gè)對象的唯一的標(biāo)識符。(你也可以使用該對象的屬性名。)
- from Cat as cat where cat.id = 123
- from Cat as cat where cat.mate.id = 69
第二個(gè)查詢是有效的。此時(shí)不需要進(jìn)行表連接!
同樣也可以使用復(fù)合標(biāo)識符。比如Person類有一個(gè)復(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
第二個(gè)查詢也不需要進(jìn)行表連接。
同樣的,特殊屬性class在進(jìn)行多態(tài)持久化的情況下被用來存取一個(gè)實(shí)例的鑒別值(discriminator value)。 一個(gè)嵌入到where子句中的Java類的名字將被轉(zhuǎn)換為該類的鑒別值。
- from Cat cat where cat.class = DomesticCat
你也可以聲明一個(gè)屬性的類型是組件或者復(fù)合用戶類型(以及由組件構(gòu)成的組件等等)。永遠(yuǎn)不要嘗試使用以組件類型來結(jié)尾的路徑表達(dá)式(path-expression) (與此相反,你應(yīng)當(dāng)使用組件的一個(gè)屬性來結(jié)尾)。 舉例來說,如果store.owner含有一個(gè)包含了組件的實(shí)體address
- store.owner.address.city // 正確
- store.owner.address // 錯(cuò)誤!
一個(gè)“任意”類型有兩個(gè)特殊的屬性id和class, 來允許我們按照下面的方式表達(dá)一個(gè)連接(AuditLog.item 是一個(gè)屬性,該屬性被映射為
- 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)可以按照一個(gè)返回的類或組件(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)的查詢可以按照一個(gè)返回的類或組件(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).
【編輯推薦】