将Postgresql查询转换为Hibernate

时间:2014-02-28 12:56:37

标签: java hibernate postgresql

在我的Java Web应用程序中,我使用Postgresql,并且一些数据表在服务器中自动填充。在数据库中,我有一个STATUS表,如下所示:

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 个答案:

答案 0 :(得分:0)

hibernate的目标是将数据库实体映射到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'

如果gpsdateiostatusId无关,那么您需要

之类的内容
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,但我不确定。

顺便说一句,我必须警告你,这些方法可能不会比你在应用程序中找到更改更好,因为它们涉及将表连接到自身,这是一项昂贵的操作;第二个查询涉及连接后的嵌套查询,这也非常昂贵。