Hibernate Criteria物件詳解(條件查詢)
Criteria介面提供createAlias 和 createCriteria 兩組方法用於完成多表關聯查詢。
createAlias(String associationPath, String alias) 採用內連線關聯。
createAlias(String associationPath, String alias, int joinType) 可以通過joinType指定連線型別。
createCriteria(String associationPath) 採用內連線關聯(返回新的Criteria物件)。
createCriteria(String associationPath, int joinType) 可以通過joinType指定關聯型別(返回新的Criteria物件 )。
例如:查詢部門為“人力資源部”的所有員工。
方法一:使用createCriteria方法。
產生的SQL語句:
程式碼中的criteria物件,是針對employee表,criteria.createCriteria(”department”) 就是建立employee表和department表的內連線。返回的是針對department表新的criteria2物件,這時再對criteria2 新增條件,就是查詢department部門表的屬性,而不是employee的屬性了。
方法二:使用createAlias 方法。
使用createAlias方法不會像createCriteria那樣返回一個新的Criteria物件,alias只是對關聯表進行別名設定,通過別名引用設定屬性。
產生的SQL語句:
3.5.投影、分組查詢 Projection
在實際開發中,進行查詢是:可能只需要返回表中的指定列資訊(投影)或者進行統計查詢(count、avg、sum、min、max),Criteria介面提供setProjection(Projection projection)方法用於實現投影查詢操作。
org.hibernate.criterion.Projections工廠類用於返回Projection投影查詢物件。
例如: 1. 查詢員工表的name和age屬性。
產生的SQL語句:
Projections.property(屬性名)也可以寫為Property.forName(屬性名 )。
2.查詢員工的總數量。
Projections提供了分組函式的查詢方法:
rowCount() 查詢記錄總數量;
count(String propertyName) 統計某列數量;
countDistinct(String propertyName) 統計某列數量(排除重複);
avg(String propertyName) 統計某列平均值;
sum(String propertyName) 對某列值求和;
max(String propertyName) 求某列最大值;
min(String propertyName) 求某列最小值。
產生的SQL語句:
3.查詢每個部門的員工數量(輸出部門的編號和數量 )。
Projections提供groupProperty(String propertyNam
-e)用於執行分組操作。
產生的SQL語句:
3.6. 設定結果集封裝策略 ResultTransformer
剛剛說了投影操作的使用,其實在Hibernate內部投影查詢是會影響到結果集的封裝策略的。先用HQL舉例說明:
session.createQuery(”from Employee”).list(); 返回 List
session.createQuery(”select count(e) from Employee e”).list(); 返回List
session.createQuery(”select name,age from Employee”).list(); 返回List
從這幾個例子我們不難發現,如果沒有指定select語句(沒有投影),那麼將返回表中的所有欄位,返回結果會被封裝到Entity實體物件Employee中,一但提供select語句(投影)後,返回的結果型別,將不再封裝到Employee物件,而是根據投影的實際型別返回,這就是投影對結果封裝策略的影響。
我們再來看之前寫過的Criteria 查詢案例:
session.createCriteria(Employee.class).list();返回 List
session.createCriteria(Employee.class).setProjection(
Projections.projectionList()
.add(Property.forName(”name”))
.add(Property.forName(”age”))); 返回 List
投影之後,返回的結果將不再被封裝到Employee物件中,這是為什麼呢?
我們一起來看看 Criteria的介面定義,不難發現在Criteria介面中提供了一個setResultTransformer(ResultTransformer resultTransformer),這個ResultTransformer就是結果集轉換策略介面,在Criteria的父介面中CriteriaSpecification定義了幾個ResultTransformer的常用實現。
ALIAS_TO_ENTITY_MAP 將結果集封裝到Map物件;
ROOT_ENTITY 將結果集封裝到根實體物件;
DISTINCT_ROOT_ENTITY 將結果集封裝到不重複的根實體物件;
PROJECTION 根據投影的結果型別自動封裝;
當進行投影查詢時,結果的封裝策略由ROOT_ENTITY 變為了PROJECTION, 所以是根據查詢資料進行封裝,而不是封裝到根物件。
瞭解上面原理後,即使只查詢name和age屬性,也可以封裝成List集合。
使用AliasToBeanResultTransformer 修改結果封裝策略,AliasToBeanResultTransformer 會根據返回列自動匹配類中屬性名,完成封裝。
產生的SQL語句: