如何将复杂的 SQL 查询转换为 JPQL?

Posted

技术标签:

【中文标题】如何将复杂的 SQL 查询转换为 JPQL?【英文标题】:How to convert complex SQL query to JPQL? 【发布时间】:2020-12-29 20:56:12 【问题描述】:

我在 SQL 中有以下查询。

这里的发件人文档表包含发件人和文档实体。

@Entity
@Table(name = "sender_document")
public class SenderDocument  

    @Id
    @Column(columnDefinition = "uuid")
    protected UUID id;

    @Column(name = "created_at")
    private LocalDateTime createdAt;

    @ManyToOne
    @JoinColumn(name = "sender_id")
    private Sender sender;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "document_id")
    private Document document;
    
    //other columns


我必须找到过期日期在开始和结束之间的所有发件人的最新文档。

select * from sender_document join
(select sender_id, max(created_at) as maxDate
from sender_document
group by sender_id ) as t2
on created_at = t2.maxDate
and t2.sender_id = sender_document.sender_id
where sender_document.document.expiry_date between 'start_date' and 'end_date'

我必须将其转换为 JPQL 或使用标准 API。我正在使用 Postgres 数据库。

如何将其转换为单个 JPQL?

【问题讨论】:

您有代表sender_document 表的实体吗?如果有,请出示。 是的,sender_document 是一个实体。 你试过了吗? 我尝试了来自 [***.com/a/20707219/10147096] 的类似问题的解决方案,但它对我不起作用。 @Shankar Ghimire,我绝对建议坚持您提供的 SO 链接中提到的查询。你能构建这样的查询吗?或者是什么问题? 【参考方案1】:

我才意识到在 JPQL 中编写复杂的查询是多么困难。

我遇到了类似下面的解决方案。

SELECT sd FROM SenderDocument sd 
where sd.createdAt = (SELECT MAX(s.createdAt) FROM SenderDocument  s 
where s.sender = sd.sender and s.document.type in :types 
and sd.document.type in :types) 
and (:mtoId is null or sd.sender.mtoId = :mtoId) and sd.document.expiryDate 
between :start and :end order by sd.createdAt asc

【讨论】:

以上是关于如何将复杂的 SQL 查询转换为 JPQL?的主要内容,如果未能解决你的问题,请参考以下文章

将此 JPQL 查询转换为 SQL 查询

如何将复杂的 sql 查询转换为 laravel Eloquent

条件查询,SQL,JPQL,HQL

使用子句 IN 从 sql 转换为 jpql

JPA JPQL简介

将具有许多连接的复杂 SQL 查询转换为 Eloquent