You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot JpaRepository获取最后N条数据:HQL查询报错求助

解决Spring Boot JpaRepository HQL查询最后2条记录的问题

嘿,这个问题我之前也碰到过!你的HQL语句报错是因为HQL不支持在FROM子句中直接使用嵌套子查询(派生表),而且limit是原生SQL的语法,在HQL的子查询里没法直接生效。给你几个可行的解决方案:

方案一:使用原生SQL查询

直接用原生SQL可以完美支持派生表和limit语法,只需要在@Query里加上nativeQuery=true,注意要对应数据库的表名和字段名(不是实体类的属性名):

@Query(value = "select * from (select * from news order by news_id desc limit 2) sub order by news_id asc", nativeQuery = true)
List<NewsDTO> findLastTwoNewsOrderAsc();

方案二:用JPA的Pageable/Sort结合内存反转

如果不想写原生SQL,可以先通过JPA的排序获取倒序的前2条记录,再在内存中反转顺序:

方法1:结合Sort和Stream

// 先按newsId倒序获取所有记录,取前2条
List<NewsDTO> lastTwoDesc = newsRepository.findAll(Sort.by(Sort.Direction.DESC, "newsId"))
    .stream()
    .limit(2)
    .collect(Collectors.toList());
// 反转列表得到正序的最后2条
Collections.reverse(lastTwoDesc);

方法2:用Pageable更高效

如果数据量很大,用Pageable可以避免查询全表:

// 第0页,每页2条,按newsId倒序
Pageable pageable = PageRequest.of(0, 2, Sort.by(Sort.Direction.DESC, "newsId"));
List<NewsDTO> lastTwoDesc = newsRepository.findAll(pageable).getContent();
// 反转顺序
Collections.reverse(lastTwoDesc);

方案三:使用HQL窗口函数(Hibernate 5.2+支持)

如果你的Hibernate版本在5.2及以上,可以用窗口函数row_number()来实现,这种写法属于标准HQL,不需要原生SQL:

@Query("select sub.news from (select news, row_number() over (order by news.newsId desc) as rn from NewsDTO news) sub where sub.rn <= 2 order by sub.news.newsId asc")
List<NewsDTO> findLastTwoNews();

额外说明

你原来的语句里还有一个小问题:子查询的别名是sub,但外层查询里直接用了news,正确的应该是sub.news(比如方案三里的写法),不过这不是主要报错原因,核心还是HQL不支持FROM子句的派生表。

内容的提问来源于stack exchange,提问作者Merwais Muafaq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:24:38