Hibernate除了處理查詢結果集中的對象之外,還可以將結果集中的結果當做行和列集來使用,這與通過JDBC執行select查詢獲得的數據的使用方式相似。因此,Hibernate也支持屬性、統計函數和Group By等查詢。
要 想使用Hibernate的投影統計功能,首先要從org.hibernate.criterion.Projections工廠類獲得 org.hibernate.criterion.Projection對象。與Restrictions類相似,Projections類提供了幾個用 來獲取Projection實例的靜態工廠方法。在獲得Projection對象之后,使用setProjection()方法將它添加到 Criteria對象中。注意,返回的結果集是Object類型,需要對結果進行適當的類型轉換。
Hibernate的Projections工廠類包含了以下幾個常用的統計函數:
① avg(String propertyName):計算屬性字段的平均值。
② count(String propertyName):統計一個屬性在結果中出現的次數。
③ countDistinct(String propertyName):統計屬性包含的不重復值的數量。
④ max(String propertyName):計算屬性值的最大值。
⑤ min(String propertyName):計算屬性值的最小值。
⑥ sum(String propertyName):計算屬性值的總和。
下面的示例演示了一些統計函數和投影列表的使用方法:
- getSession().beginTransaction();
- Criteria Crit = getSession().createCriteria(Product.class);
- ProjectionList projList = Projections.projectionList();
- projList.add(Projections.max("price"));
- projList.add(Projections.min("price"));
- projList.add(Projections.avg("price"));
- projList.add(Projections.countDistinct("description"));
- Crit.setProjection(projList);
- List result = Crit.list();
- getSession().getTransaction().commit();
上述示例執行了多個統計投影。當執行多個統計投影時,會獲取一個List,並且是一個Object類型的List,其中依次包含所有的統計投影結果。
使用投影的一個好處就是,獲得的結果是單獨的屬性而不是實體類。例如,一個產品表中包含有很多字段,我們想要獲取產品表中的名稱和描述,而不需要將完整的實體加載到內存中。
- Criteria Crit = getSession().createCriteria(Product.class);
- ProjectionList projList = Projections.projectionList();
- projList.add(Projections.property("name"));
- projList.add(Projections.property("description"));
- Crit.setProjection(projList);
- List result = Crit.list();
使 用這種查詢風格可以減少應用服務器和數據庫服務器之間的網絡通信量。但是,如果客戶機的內存容量的確是有限的,那么這種查詢方式可以避免處理大型數據集對 內存的壓力。如果不確定以后是否需要一個完整的結果集,這得要執行另外一次查詢,反而降低了查詢性能。所以只能在適當的時候才使用Hibernate的投 影功能。
那么如何獲得結果集中的不重復的結果呢?方法為:
distinct(Projection proj):統計屬性的不重復值。
- getSession().beginTransaction();
- Criteria criteria = getSession().createCriteria(Transaction.class);
- ProjectionList proList = Projections.projectionList();
- proList.add(Projections.distinct(Projections.property("module")));
- criteria.setProjection(proList);
- criteria.addOrder(Order.asc("orderSign"));
- list = criteria.list();
- getSession().getTransaction().commit();
最后,可以使用groupProperty投影對結果集進行分組(使用SQL的GROUP BY子句)。下面的示例安裝名稱和價格對產品進行分組:
- Criteria Crit = getSession().createCriteria(Product.class);
- ProjectionList projList = Projections.projectionList();
- projList.add(Projections.groupProperty("name"));
- projList.add(Projections.groupProperty("price"));
- Crit.setProjection(projList);
- List result = Crit.list();
