2014-02-28 35 views
1

在我的Java Web應用程序中我使用PostgreSQL和一些數據表都是在服務器自動填充。在數據庫中,我有一個狀態表,如下圖所示:轉換PostgreSQL的查詢到Hibernate

enter image description here

我想選擇與所選擇的日期,並在車輛仍保持連接狀態之間的車輛數據。簡單地說,我想要選擇上表中綠色的數據,這意味着我首先需要io1 = true時的數據,以及最後一次io1 = true時io1 = false時的數據。我有postgresql查詢語句,這正好給我所需的數據;但是,由於我的應用程序邏輯,我必須將其轉換爲HQL。

工作,PostgreSQL的查詢:

WITH cte AS 
(SELECT iostatusid, mtstrackid, io1,io2,io3, gpsdate, 
     (io1 <> LAG(io1) OVER (PARTITION BY mtstrackid 
              ORDER BY gpsdate) 
     ) AS status_changed 
FROM iostatus 
WHERE mtstrackid = 'redcar' AND gpsdate between '2014-02-28 00:00:00' and '2014-02-28 23:59:59' 
) 
SELECT iostatusId, mtstrackid, io1, io2, io3,gpsdate 
FROM cte 
WHERE status_changed 
OR io1 AND status_changed IS NULL 
ORDER BY gpsdate ; 

應該如何我上面的查詢轉換爲HQL或我怎麼能檢索與HQL所需的數據?

+1

你可以使用本機查詢只需要調用數據庫。然後你可以使用上面的代碼。我懷疑這裏的任何人會用HQL來翻譯這個,如果你提供了足夠的信息,這也是令人懷疑的。 – Magnilex

+0

'ClassCastException'。 –

+1

我不認爲HQL支持公用表表達式甚至窗口函數。它只支持最基本的SQL語句。 –

回答

0

休眠的目標是映射數據庫實體Java對象。這種複雜的查詢本身不是實體。這違背了hibernate的精神。

如果該查詢應用程序中的邏輯產生的實體,我建議把結果放到一個表,並應用Hibernate查詢該表。

如果該查詢產生某種聚集或總結,有兩種可能的方式:

  • 一種方法是從iostatus表中檢索實體休眠後,計算在應用此聚集/彙總。

  • 如果此查詢與您的應用程序邏輯無關,那麼您可以使用Hibernate的Native SQL interface並直接執行查詢。 (你甚至可以使用JPA如果你願意來操縱兩個數據庫連接。)

如果您確實需要將其轉換爲HQL,你需要消除的功能分區。如果iostatusId順序是一致的gpsdate順序,你可以做到這一點類似於

SELECT i2.* 
FROM iostatus i1 
INNER JOIN iostatus i2 ON i1.iostatusId = i2.iostatusId - 1 
         AND i1.io1 <> i2.io1 
         AND i1.mstrackid = i2.mstrackid 
WHERE i2.mtstrackid = 'redcar' AND 
     i2.gpsdate between '2014-02-28 00:00:00' and '2014-02-28 23:59:59' 

如果gpsdate是沒有絲毫關係iostatusId那麼你需要像

SELECT i2.* 
FROM iostatus i1 
INNER JOIN iostatus i2 ON i1.gpsdate < i2.gpsdate 
         AND i1.io1 <> i2.io1 
         AND i1.mstrackid = i2.mstrackid 
WHERE i2.mtstrackid = 'redcar' AND 
     i2.gpsdate between '2014-02-28 00:00:00' and '2014-02-28 23:59:59' AND 
     NOT EXISTS (SELECT * FROM iostatus i3 
        WHERE i3.gpsdate > i1.gpsdate AND 
         i2.gpsdate > i3.gpsdate AND 
         i3.io1 = i1.io1 AND 
         i1.mstrackid = i3.mstrackid) 

我猜這兩個查詢可以轉換爲HQL,但我不確定。

通過我必須警告你,順便說一下,這些方法可能不會有更好的表現,然後找到你的應用程序的變化,因爲它們涉及加入到表本身,這是一個昂貴的操作;第二個查詢涉及連接後的嵌套查詢,這也很昂貴。

+0

我編輯了我的問題。在我的應用程序邏輯中,上面的查詢總結了我想要的所需數據的iostatus表。但是,我必須將其轉換爲HQL查詢。如果我在從表中檢索所有數據後對數據進行總結,則會產生性能問題,因爲會有大量數據。 – nudaStck

+1

我仍然不明白你的表模式和查詢完美。但是如果你絕對需要在HQL中編寫這個查詢,你需要重構它。您不能在HQL中使用CTE和Window分區。這些東西不適用於每個數據庫供應商,HQL獨立於供應商。 消除CTE很簡單,使用嵌套查詢。 CTE只是語法糖。 我想你可以很容易地消除窗口分區。實際上,由於mstrackid的where子句,您似乎並未使用分區。 – infiniteRefactor

+0

我在我的問題中詳細解釋了一切。你能看看嗎? – nudaStck