1. 程式人生 > >Hibernate Criteria物件詳解(條件查詢)

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語句: