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