Spring JPA:使用分页查找多个 ID
Posted
技术标签:
【中文标题】Spring JPA:使用分页查找多个 ID【英文标题】:Spring JPA: find by multiple IDs with Pagination 【发布时间】:2021-06-22 02:22:27 【问题描述】:如何将分页应用于以下查询:
@Repository
public interface PostRepository extends JpaRepository<Post, Long>
@Query("select b from Building b where b.id in :ids" )
Page<Post> findByIds(@Param("ids") List<Long> postIdsList);
...
所有现有示例均基于接受Pageable
对象的标准findAll
方法:public Page findAll(Pageable pageable);
。
问题是:
控制器方法签名应该是什么 存储库方法参数应该是什么 应如何以及将哪些参数传递给控制器方法 我应该总是为每个请求拆分帖子 ID Spring 是否会进行一次查询并将所有找到的帖子保存在内存中,或者每次下一页/上一页都会点击查询?如果是这样,它如何找出用于查找下一个/上一个帖子的 ID?最初的实现如下:
@RestController
class PostsController
@Autowired
private PostService postService;
@GetMapping("/posts", params = "ids")
public List<Post> getPaginatedPosts(@RequestParam List<Long> ids)
return postService.findPaginatedPosts(ids);
@Repository
@Repository
public interface PostRepository extends JpaRepository<Post, Long>
@Query("select b from Building b where b.id in :ids" )
Page<Post> findByIds(@Param("ids") List<Long> postIdsList);
...
我省略了 PostServiceImpl
中的代码 qui 实现了 PostService
并且只调用了 PostRepository#findByIds
方法。
【问题讨论】:
baeldung.com/rest-api-pagination-in-spring 这引出了一个问题:如果客户端知道它应该获取的 id,为什么不通过简单地限制请求中发送的 id 列表来处理分页? @crizzis:因为前面有超过 20 个 ID,通过添加分页/排序参数来调整 URL 比玩集合并到处剪切它更容易页。所以我更愿意让 Spring 就地执行。更重要的是,我认为这就是大多数分页库的工作方式。 【参考方案1】:试试这个:
@Repository
public interface PostRepository extends JpaRepository<Post, Long>
@Query( "select o from Building b where id in :ids" )
Page<Post> findByIds(@Param("ids") List<Long> postIdsList,Pageable pageRequest);
...
在控制器中询问 pageSize 和 pageNo,如果它为空,则设置一个默认值,例如 pageNo = 0, pageSize=10。
将这些值传递给服务层服务应该创建可分页对象调用findByIds(ids, pagable);
并将页面返回给控制器。
你可以参考这个: https://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-seven-pagination/
【讨论】:
感谢您的链接,即使它是 2012 年的,它仍然有用:)。我还看了最新的Spring Data Rest docs。【参考方案2】:这是我给你的解决方案,加上上面的 cmets 建议。
-
定义一个可以扩展
JpaRepository
或 PagingAndSortingRepository
的存储库,如下所示:
@Repository
public interface PostRepository extends JpaRepository<Post, Long>
@Query("select p from Post p where p.id in :ids" )
Page<Post> findByIds(@Param("ids") List<Long> postIdsList);
...
-
创建服务类及其实现:
public interface PostService
List<PostDTO> getPostsList(List<Long> ids, Pageable pageable);
...
@Service
@Slf4j
public class PostServiceImpl implements PostService
...
@Autowired
private PostRepository postRepository;
...
@Override
public List<PostDTO> getPostsList(List<Long> ids, Pageable pageable)
List<PostDTO> resultList = new ArrayList<>();
Page<Post> paginatedPosts = postRepository.findByIds(ids, pageable);
List<Post> posts = paginatedPosts.getContent();
posts.forEach(post -> resultList.add(convertToPostDTO(post)));
return resultList;
最后,PostsController
部分:
@RestController
@RequestMapping("/api")
class PostsController
@Autowired
private PostService postService;
...
@GetMapping(value = "/posts", params = "ids")
public ResponseEntity <List<PostDTO>>getPostsList(@RequestParam List<Long> ids, Pageable pageable)
List<PostDTO> postsList = postService.getPostsList(ids, pageable);
return new ResponseEntity<>(postsList, HttpStatus.OK);
请求应该包含page
和size
URL参数(默认情况下,page
是0
和size
是20
):
http://localhost:8080/api/posts?ids=1050,1049,1048,1043,1042,1041,1040,1039,1038&size=5&page=1&sort=id
在上面的示例中,我总共有 9 条记录,我明确设置了参数以将结果列表限制为 5 条并仅显示第二页以及按 id 对它们进行排序。
如果您不提供它们,将使用默认值(page = 0,size = 20)。
【讨论】:
以上是关于Spring JPA:使用分页查找多个 ID的主要内容,如果未能解决你的问题,请参考以下文章
java web spring jpa 在以接口为dao的方法里使用原生sql,联合查找没有对应实体,用啥来接收? 求大神