java - 将 Postgresql 查询转换为 Hibernate

标签 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 检索所需的数据?

最佳答案

hibernate 的目标是将数据库实体映射到 java 对象。这种复杂的查询本身并不是实体。这违背了hibernate的精神。

如果此查询在您的应用程序逻辑中生成一个实体,我建议将结果放入表中并将 Hibernate 查询应用于该表。

如果此查询生成某种聚合或摘要,则有两种可能的方式:

  • 一种方法是在使用 hibernate 从 iostatus 表中检索实体后,在您的应用程序中计算此聚合/摘要。

  • 如果此查询与您的应用程序逻辑无关,那么您可以使用 Native SQL interface Hibernate 并直接执行查询。 (如果您愿意操作两个数据库连接,您甚至可以使用 JPA。)

如果一定要转成HQL,就需要去掉partition函数。如果 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,但我不确定。

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

关于java - 将 Postgresql 查询转换为 Hibernate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22095854/

相关文章:

java - spring boot 嵌入式tomcat获取资源问题

java - Android NDK 库仅在运行时不加载三星 galaxy 4.0.2 手机

java - Spring JPA,CrudRepository 的 save 方法是否立即提交到 DB?

ajax - 高效地对数据库中的时间序列数据进行子采样

sql - 如何分离列数据从一个表复制到另一个表?

java - 占位符的 setImageDrawable 与 setBackground

java - 从 SonarQube 4.1.1 分析中排除 Java 测试文件

java - 通过导致 PSQLException 的 Hibernate 和 PostgreSQL 执行查询的差异

java - 尝试将数据添加到数据库时出现未知列

sql - 查询邻接表中最远的 child