2008-11-26 94 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

或許,如果你發佈的表結構,這可能會給予更多的上下文你的問題?