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属性所组成的集合。