hibernate投影、聚合和分组实例介绍



hibernate投影、聚合和分组实例。投影运算实际上就是一个基于列的运算,通常用于投影到指定列(也就是过滤其他列,类似select子句的作用),还可以完成SQL语句中常用的分组、组筛选等功能。

Hibernate的条件过滤中使用Projection代表投影运算,Projection是一个接口,而Projections作为Projection的工厂,负责生成Projection对象。

一旦产生了Projection对象之后,就可通过Criteria提供的setProjection(Projection projection)方法来进行投影运算。从该方法上看,每个Criteria只能接受一个投影运算,似乎无法进行多个投影运算,但实际上Hibernate又提供了一个ProjectionList类,该类是Projection的子类,并可以包含多个投影运算,通过这种方式即完成多个投影运算。

因此,一个条件查询的投影运算通常有如下程序结构:

List cats = session.createCriteria(Cat.class)

.setProjection(Projections.projectionList()

.add(Projections.rowCount())

.add(Projections.avg(“weight”))

.add(Projections.groupProperty(“color”))

).addOrder(Order.asc(“color”))

.list();

注意:使用条件查询的投影运算时,不能使用显示的分组子句,但某些投影类型的实质就是分组投影,这些投影元素将出现在SQL的group by子句中——如上的groupProperty(“color”)投影。

投影运算的实质和group by子句、聚集函数的功能大致一致。

除此之外,如果我们希望对分组(投影)后属性进行排序,那就需要为投影运算指定一个别名。为投影运算指定别名有3种方法:

(1)使用Projections的alias()方法为指定投影指定别名。一旦为projection指定了别名,则程序就可以根据该Projection别名来进行其他额外操作了,比如排序。条件查询片段如下:

List l = session.createCriteria(Enrolment.class)

.setProjection(Projections.projectionList()

//按course进行分组

.add(Projections.groupProperty(“course”))

//统计记录条数,并为统计结果指定别名c

.add(Projections.alias(Projections.rowCount(),” c”))

).addOrder(Order, asc(“c”))

.list();

(2)使用SimpleProjection的as()方法为自身指定别名。


List l = session.createCriteria(Enrolment.class)

.setProjection(Projections.projectionList()

//按course进行分组

.add(Projections.groupProperty(“course”).as(“c”))

//统计记录条数,并为统计结果指定别名c

.add(Projections.rowCount())

).addOrder(Order, asc(“c”))

.list();

(3)使用ProjectionList的add()方法添加投影时指定别名。

ProjectionList的add()方法有两个重载形式,一个是直接添加投影,另一个是在添加投影时指定别名。条件查询片段如下:

List l = session.createCriteria(Enrolment.class)

.setProjection(Projections.projectionList()

//按course进行分组,指定别名为c

.add(Projections.groupProperty(“course”),(“c”))

//统计记录条数,并为统计结果指定别名rc

.add(Projections.rowCount(),”rc”)

).addOrder(Order, asc(“c”))

.list();

除此之外,Hibernate还提供了Property执行投影运算,Property投影的作用类似于SQL语句中的select,条件查询的结果只有被Property投影的列才会被选出,条件查询片段如下:

List l = session.createCriteria(Student.class)

.setProjection(Property.forName(“name”))

.list();

上面条件查询执行的结果不再是Student对象集合,而是name属性所组成的集合。