如何限制关联查询结果大小?获取带降序前5评论的文章实体
解决JPA关联集合限制结果数量的问题
嘿,这个场景我太熟悉了!用@OrderBy确实能帮我们给评论按日期排序,但JPA标准注解里确实没有直接限制关联集合大小的配置,不过有几个实用的方案可以解决这个需求,我给你详细说说:
方案一:自定义JPQL查询(推荐,跨数据库友好)
你可以在ArticleRepository里写一个带分页的JPQL查询,通过JOIN FETCH加载评论,同时利用Pageable来限制返回的评论数量,记得加上DISTINCT避免重复的Article实体:
import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @Query("SELECT DISTINCT a FROM Article a JOIN FETCH a.comments c WHERE a.id = :articleId ORDER BY c.createdDate DESC") Article findArticleWithTop5Comments(@Param("articleId") Long articleId, Pageable pageable);
调用的时候,传入PageRequest.of(0, 5)就能获取到按日期降序排列的前5条评论:
Article article = articleRepository.findArticleWithTop5Comments(1L, PageRequest.of(0, 5));
方案二:原生SQL查询(适合特定数据库优化)
如果你的项目不需要跨数据库,用原生SQL会更直接,比如MySQL里可以用LIMIT,PostgreSQL用FETCH FIRST 5 ROWS ONLY:
@Query(value = "SELECT a.*, c.* FROM article a JOIN comment c ON a.id = c.article_id WHERE a.id = :articleId ORDER BY c.created_date DESC LIMIT 5", nativeQuery = true) Article findArticleWithTop5CommentsNative(@Param("articleId") Long articleId);
不过这种方式的缺点是和数据库耦合,换数据库的时候需要修改SQL语句。
方案三:内存中截断(不推荐,性能差)
如果你的评论数量本来就很少,也可以先加载所有评论,然后在内存里截取前5条,但这种方式会加载所有评论数据,数据量大的时候性能会很差,不建议在生产环境用:
Article article = articleRepository.findById(articleId).orElseThrow(); List<Comment> top5Comments = article.getComments().stream() .sorted(Comparator.comparing(Comment::getCreatedDate).reversed()) .limit(5) .collect(Collectors.toList()); article.setComments(top5Comments);
注意事项
- 用
JOIN FETCH的时候,一定要注意避免N+1查询问题,上面的JPQL方案已经通过FETCH一次性加载了Article和评论,不会有这个问题。 - 如果需要批量获取多个Article的前5条评论,建议用批量查询的方式,避免循环查询每个Article的评论。
内容的提问来源于stack exchange,提问作者ArslanAnjum
相关产品推荐
相关产品推荐

