如何对JPA查询的子查询强加LIMIT?

exp*_*ert 10 jpa subquery jpql

是否可以在JPA查询中对子查询施加LIMIT?

我在纯SQL中有以下查询

select * from ipinfo 
where RangeEnd < (select RangeStart from ipinfo where RangeStart >= 1537022421 order by RangeStart asc limit 1) and (1537022421 <= RangeEnd)
ORDER BY RangeEnd desc
limit 1
Run Code Online (Sandbox Code Playgroud)

将它直接转换为JPQL我会有类似的东西

select obj from IpInfo obj
where obj.rangeEnd < (select obj2.rangeStart from IpInfo obj2 where obj2.rangeStart >= ?1 order by obj2.rangeStart asc limit 1) and (?1 <= obj.rangeEnd)
ORDER BY obj.rangeEnd desc
limit 1
Run Code Online (Sandbox Code Playgroud)

由于我不能在JPQL中使用LIMIT,我必须使用setMaxResults(1)它.但是子查询呢?

更新:

我决定暂时使用@NamedNativeQuery它,但它是特定于DB的代码.如果你们可以推荐纯粹的JPA解决方案,我会非常感激.

Seb*_*ber 4

我不知道如何使用 JPQL 做到这一点,但您可能可以使用 Criteria API 来处理它,至少我很确定我们可以使用 Hibernate 标准子查询来做到这一点,所以我想即使 JPA 标准也可以使用 JPA api 对我来说似乎有点令人困惑。

检查这个: JPA 2.0、Criteria API、子查询、表达式

无论如何,您甚至不需要对子查询进行限制。

您的原始查询: select RangeStart from ipinfo where RangeStart >= 1537022421 order by RangeStart asc limit 1 看来您想要 ipinfo 列表的最小 RangeStart,它正好高于给定值。min 函数就是为此而设计的。

您可以简单地使用这样的子查询:

select min(RangeStart) from ipinfo where RangeStart >= 1537022421
Run Code Online (Sandbox Code Playgroud)

即使您需要在子查询中返回其他 ipinfo,也可以通过以下方式完成:

select RangeEnd, anything,blabla from ipinfo where RangeStart = (
    select min(RangeStart) from ipinfo where RangeStart >= 1537022421
)
Run Code Online (Sandbox Code Playgroud)