2008-11-26 99 views
6

我有一个类型为datetime的时间戳字段的表。我需要将定义的开始时间和结束时间之间的数据聚合到代表等长时间间隔的x组中,其中x作为函数参数提供。按时间间隔休眠组

什么是最好的方式与Hibernate做到这一点?

编辑:一些解释

MySQL表:

data_ts: datetime pk 
value1 : int 
value2 : bigint 
... 

实体类:

Calendar dataTs; 
Integer value1; 
BigDecimal value2; 
... 

我要寻找一个HQL查询,确实有点像

select max(c.value1), avg(c.value2) from MyClass c 
    where c.dataTs between :start and :end group by <interval> 

谁在哪里le时间段被分成x个相同大小的时间间隔。

实施例:

Start : 2008-10-01 00:00:00 
End : 2008-10-03 00:00:00 (2 days) 
Groups: 32 

将需要以1.5小时的时间间隔进行分组(48小时/ 32):

2008-10-01 00:00:00 - 2008-10-01 01:29:59 
2008-10-01 01:30:00 - 2008-10-01 02:59:59 
2008-10-01 02:00:00 - 2008-10-01 04:29:59 
... 

回答

9

我试图解决同样的问题。我必须在一天内将数据分组2小时。事实上,“纯粹的”Hibernate不应该以这种方式使用。所以我将原生SQL投影添加到了Hibernate的标准中。对于你的情况可能是这样的(我使用MySQL的语法&功能):

int hours = 2; // 2-hours interval 

Criteria criteria = session.createCriteria(MyClass.class) 
      .add(Restrictions.ge("dataTs", start)) 
      .add(Restrictions.le("dataTs", end)); 


ProjectionList projList = Projections.projectionList(); 
     projList.add(Projections.max("value1")); 
     projList.add(Projections.avg("value2")); 
     projList.add(Projections.sqlGroupProjection(
      String.format("DATE_ADD(DATE(%s_.dataTs), INTERVAL(HOUR(%s_.dataTs) - HOUR(%s_.dataTs) %% %d) HOUR) as hourly", criteria.getAlias(), criteria.getAlias(), criteria.getAlias(), hours), 
      String.format("DATE_ADD(DATE(%s_.dataTs), INTERVAL(HOUR(%s_.dataTs) - HOUR(%s_.dataTs) %% %d) HOUR)", criteria.getAlias(), criteria.getAlias(), criteria.getAlias(), hours), 
      new String[]{ "hourly" }, 
      new Type[]{ Hibernate.TIMESTAMP }) 
     ); 
     criteria.setProjection(projList); 

List results = criteria 
      .setCacheable(false) 
      .list(); 

的代码看起来有点有点难看,但它解决了这个问题。希望总体思路对你有所帮助。

3

Hibernate是对对象图之间的映射(实体和值类型)及其在关系数据库中的表示。

从您的问题描述中,您没有真正提到您正在建模的任何实体,所以我会建议您放下一个本机SQL查询。

http://www.hibernate.org/hib_docs/reference/en/html/querysql.html

或许,如果你发布的表结构,这可能会给予更多的上下文你的问题?