[转]Hibernate Projections(投影、统计、不重复结果)
原文出处:http://www.sunchis.com/html/java/hbm/2011/0309/265.html
用来进行聚合操作,和sql中的聚合类似.求和/求平均值/统计记录数/...等等.
还有用来获取获取对象的某些属性(表字段)或属性集合.正常情况下,查询返回的是对象或对象的集合.使用投影的话就可以只返回你需要的属性值.即Hibernate不把记录封装对象了,只返回你在投影中设置的属性的值(值的集合)的数组.
---------
Hibernate除了处理查询结果集中的对象之外,还可以将结果集中的结果当做行和列集来使用,这与通过JDBC执行select查询获得的数据的使用方式相似。因此,Hibernate也支持属性、统计函数和GroupBy等查询。
要想使用Hibernate的投影统计功能,首先要从org.hibernate.criterion.Projections工厂类获得org.hibernate.criterion.Projection对象。与Restrictions类相似,Projections类提供了几个用来获取Projection实例的静态工厂方法。在获得Projection对象之后,使用setProjection()方法将它添加到Criteria对象中。注意,返回的结果集是Object类型,需要对结果进行适当的类型转换。
Hibernate的Projections工厂类包含了以下几个常用的统计函数:
①avg(StringpropertyName):计算属性字段的平均值。
②count(StringpropertyName):统计一个属性在结果中出现的次数。
③countDistinct(StringpropertyName):统计属性包含的不重复值的数量。
④max(StringpropertyName):计算属性值的最大值。
⑤min(StringpropertyName):计算属性值的最小值。
⑥sum(StringpropertyName):计算属性值的总和。
下面的示例演示了一些统计函数和投影列表的使用方法:
getSession().beginTransaction();
CriteriaCrit=getSession().createCriteria(Product.class);
ProjectionListprojList=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);
Listresult=Crit.list();
getSession().getTransaction().commit();
上述示例执行了多个统计投影。当执行多个统计投影时,会获取一个List,并且是一个Object类型的List,其中依次包含所有的统计投影结果。
使用投影的一个好处就是,获得的结果是单独的属性而不是实体类。例如,一个产品表中包含有很多字段,我们想要获取产品表中的名称和描述,而不需要将完整的实体加载到内存中。
CriteriaCrit=getSession().createCriteria(Product.class);
ProjectionListprojList=Projections.projectionList();
projList.add(Projections.property("name"));
projList.add(Projections.property("description"));
Crit.setProjection(projList);
Listresult=Crit.list();
使用这种查询风格可以减少应用服务器和数据库服务器之间的网络通信量。但是,如果客户机的内存容量的确是有限的,那么这种查询方式可以避免处理大型数据集对内存的压力。如果不确定以后是否需要一个完整的结果集,这得要执行另外一次查询,反而降低了查询性能。所以只能在适当的时候才使用Hibernate的投影功能。
那么如何获得结果集中的不重复的结果呢?方法为:
distinct(Projectionproj):统计属性的不重复值。
getSession().beginTransaction();
Criteriacriteria=getSession().createCriteria(Transaction.class);
ProjectionListproList=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的GROUPBY子句)。下面的示例安装名称和价格对产品进行分组:
CriteriaCrit=getSession().createCriteria(Product.class);
ProjectionListprojList=Projections.projectionList();
projList.add(Projections.groupProperty("name"));
projList.add(Projections.groupProperty("price"));
Crit.setProjection(projList);
Listresult=Crit.list();