首页 > 解决方案 > 如何在 REST 服务中进行分页?

问题描述

我必须编写一些 REST 服务,它应该处理一百万个条目并以 JSON 格式向用户返回响应。我正在使用 Spring 编写一些 REST 控制器并进行分页。

public List<ContactDto> getAllContacts() {

        double countItems = contactRepo.count();
        int pages = (int) Math.ceil(countItems / totalItemsPerPage);

        List<Contact> contacts = new ArrayList<>();
        for (int i = 0; i < pages; i++) {
            Page<Contact> page = contactRepo.findAll(PageRequest.of(i, totalItemsPerPage));
            contacts.addAll(page.stream().collect(Collectors.toList()));
        }

        return contacts.stream()
                .map(entity -> new ContactDto(entity.getId(), entity.getName()))
                .collect(Collectors.toList());
    }

我是春天和分页的新手。

在这种方法中是有感觉还是我做错了什么?

我的意思是我想知道我使用的是分页写入还是错误?

谢谢您的帮助!

标签: javaspringspring-bootspring-data-jpa

解决方案


似乎您正在从所有页面收集所有联系人,这没有意义,因为您将所有数据存储在内存中,否定了所有延迟加载的好处。

我建议如下:

1.Rest 控制器应该能够接受 pageNumber 和 pageSize 参数:

@GetMapping(value="/uri/{pageNumber}/{pageSize}")
public List<Contact> getContactsPage(@PathVariable("pageNumber") final Integer pageNumber, @PathVariable("pageSize") final Integer pageSize) {
//service or repository call
}

2.Repository接口应该扩展PagingAndSortingRepository:

public interface ContactRepository extends PagingAndSortingRepository<Contact, Long> {
    Page<Contact> fingAll(Pageable pageable);
}

3.在您的服务或控制器中直接创建一个 Pageable 对象并将其作为 ContactRepository#fingAll() 参数传递:

final Pageable contactsPageable = PageRequest.of(pageNumber, pageSize);

4.如有必要,将页面映射到 DTO。


推荐阅读