【问题标题】:Conversion of List to Page in SpringSpring中List到Page的转换
【发布时间】:2016-10-11 11:59:19
【问题描述】:

我正在尝试在春季将列表转换为页面。我已经使用

对其进行了转换

new PageImpl(users, pageable, users.size());

但现在我遇到了排序和分页本身的问题。当我尝试传递大小和页面时,分页不起作用。

这是我正在使用的代码。

我的控制器

    public ResponseEntity<User> getUsersByProgramId(
        @RequestParam(name = "programId", required = true) Integer programId Pageable pageable) {

    List<User> users = userService.findAllByProgramId(programId);
    Page<User> pages = new PageImpl<User>(users, pageable, users.size());

    return new ResponseEntity<>(pages, HttpStatus.OK);
}

这是我的用户回购

public interface UserRepo extends JpaRepository<User, Integer>{

public List<User> findAllByProgramId(Integer programId);

这是我的服务

    public List<User> findAllByProgramId(Integer programId);

【问题讨论】:

  • 好像你用错了。您检索表格的所有元素,然后将它们包装到PageImpl 中。但是您应该将PageRequest 传递给您的服务内的存储库以使其工作。你也可以发布你的服务方法和存储库的代码吗?
  • 是的,我肯定会发布它们,但它们对于 Impl 方法来说是相当长的。但我会发布存储库一个

标签: java spring list pagination spring-data


【解决方案1】:

这是分页列表的正确答案

public ResponseEntity<User> getUsersByProgramId(
            @RequestParam(name = "programId", required = true) Integer programId, Pageable pageable) {
        List<User> users = userService.findAllByProgramId(programId);

        final int toIndex = Math.min((pageable.getPageNumber() + 1) * pageable.getPageSize(),
                    bidList.size());
        final int fromIndex = Math.max(toIndex - pageable.getPageSize(), 0);
        Page<User> pages = new PageImpl<User>(users.subList(fromIndex, toIndex), pageable, users.size());
    
        return new ResponseEntity<>(pages, HttpStatus.OK);
}

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。我使用了子列表:

    final int start = (int)pageable.getOffset();
    final int end = Math.min((start + pageable.getPageSize()), users.size());
    final Page<User> page = new PageImpl<>(users.subList(start, end), pageable, users.size());
    

    【讨论】:

    • 它在我的情况下不起作用!你的 list.size() 是指 users.size() 吗?
    • @OliverGierke 我同意您可以直接从存储库中检索Page,但情况并非总是如此,例如,如果您的实体有一个 OneToMany 关联可以为您提供List,并且您想将其公开为Page
    • 对我来说太棒了,你让我头疼了好几天。
    • 没试过,但即使有效,但效率不高。它正在从数据库中检索所有用户并返回一个子列表。理想的情况是从数据库中仅检索将从请求中提供服务的分页用户。
    • org.springframework.data.domain.Pageable.getOffset() 返回一个 long,所以我认为您需要将 pageable.getOffset() 转换为 long 或更改 start 的类型
    【解决方案3】:

    在JHipster框架中有一个接口PageUtil

    static <T> Page<T> createPageFromList(List<T> list, Pageable pageable) {
        if (list == null) {
            throw new IllegalArgumentException("To create a Page, the list mustn't be null!");
        }
    
        int startOfPage = pageable.getPageNumber() * pageable.getPageSize();
        if (startOfPage > list.size()) {
            return new PageImpl<>(new ArrayList<>(), pageable, 0);
        }
    
        int endOfPage = Math.min(startOfPage + pageable.getPageSize(), list.size());
        return new PageImpl<>(list.subList(startOfPage, endOfPage), pageable, list.size());
    }
    

    【讨论】:

      【解决方案4】:

      基于@shilaimuslm 评论实现。在这种情况下,如果 start > end 在 subList 中,则不会抛出异常。

      List<User> users = // ...
      
      Pageable paging = PageRequest.of(pagePagination, sizePagination);
      int start = Math.min((int)paging.getOffset(), users.size());
      int end = Math.min((start + paging.getPageSize()), users.size());
      
      Page<User> page = new PageImpl<>(users.subList(start, end), paging, users.size());
      

      【讨论】:

      • 非常感谢,很好的例子!
      【解决方案5】:

      根据您的要求,不要返回完整的数组列表,而是取 subblist。 您将从请求正文中的“可分页”对象中获得“偏移”和大小。

      new PageImpl<User>(users.subList(start, end), pageable, users.size());

      【讨论】:

        【解决方案6】:

        你应该按照 dubonzi 的 answer 的建议去做。

        如果您仍想对给定的List 使用分页,请使用PagedListHolder

        List<String> list = // ...
        
        // Creation
        PagedListHolder page = new PagedListHolder(list);
        page.setPageSize(10); // number of items per page
        page.setPage(0);      // set to first page
        
        // Retrieval
        page.getPageCount(); // number of pages 
        page.getPageList();  // a List which represents the current page
        

        如果您需要排序,请使用另一个 PagedListHolder constructorMutableSortDefinition

        【讨论】:

        • 你能解释一下在这种情况下如何使用PagedListHolderMutableSortDefinition吗?
        【解决方案7】:

        这可能是解决方案。排序和分页也可以这样工作:

        控制器:

        public ResponseEntity<User> getUsersByProgramId(
           @RequestParam(name = "programId", required = true) Integer programId Pageable pageable) {
               Page<User> usersPage = userService.findAllByProgramId(programId, pageable);
               Page<User> pages = new PageImpl<User>(usersPage.getContent(), pageable, usersPage.getTotalElements());
        
               return new ResponseEntity<>(pages, HttpStatus.OK);
        }
        

        服务:

        Page<User> findAllByProgramId(Integer programId, Pageable pageable);
        

        存储库:

        public interface UserRepo extends JpaRepository<User, Integer>{
               public Page<User> findAllByProgramId(Integer programId, Pageable pageable);
        }
        

        这样,我们也可以返回不同的实体页面。

        【讨论】:

          【解决方案8】:

          为此有一个Page implementation

          Page<Something> page = new PageImpl<>(yourList);
          

          【讨论】:

          • 请注意,这个解决方案根本没有使用 Pageable 对象
          • @chomp 你能进一步解释原因吗?
          • @TharinduEranga 因为,例如,如果您收到一个 Pageable 对象,显示 pageSize = 20 或 pageNumber = 10,它会忽略它并返回所有结果
          • 如果您更喜欢自己构建 PageImpl 恕我直言,@shilaimuslm 的答案要准确得多
          • 我只需要模拟一个 Page 对象进行测试。所以这是正确的。
          【解决方案9】:
          Try This:
          
          public Page<Patient> searchPatientPage(SearchPatientDto patient, int page, int size){
                  List<Patient> patientsList = new ArrayList<Patient>();
                  Set<Patient> list=searchPatient(patient);
                  patientsList.addAll(list);
                  int start =  new PageRequest(page, size).getOffset();
                  int end = (start + new PageRequest(page, size).getPageSize()) > patientsList.size() ? patientsList.size() : (start + new PageRequest(page, size).getPageSize());
          
                  return new PageImpl<Patient>(patientsList.subList(start, end), new PageRequest(page, size), patientsList.size());
              }
          

          【讨论】:

          • 很棒的代码,但我想最好检查 start 和 end 如下 if(start (patientsList.subList(start, end), new PageRequest(页,大小),患者列表.size());因为如果开始比结束大,它就不会真正
          【解决方案10】:
          //1) For a boot application create a paging repository interface
          public interface PersonRepository extends PagingAndSortingRepository<Person, 
          String> {
          // Common CURD method are automatically implemented
          }
          //2) create a service Interface
          public interface PersonService {
              Page<Person> listAllByPage(Pageable pageable); // Use common CURD findAll() method
              Page<Object> listSpecByPage(Pageable pageable, String x);
          
          }
          //3) create a service Impl Class of service interface
          @Service
          public class PersonServiceImpl implements PersonService {
          
              final PersonRepository personRepository;
          
              @Autowired
              PersonServiceImpl(PersonRepository personRepository){
              this.personRepository = personRepository;
              }
          
              @Override
              public Page<Person> listAllByPage(Pageable pageable) {
                    return personRepository.findAll(pageable);
              }
              @Override
              public Page<Object> listSpecByPage(Pageable pageable, String path) {
                  List<Object> objectlist = new ArrayList<Object>();
                  // Do your process to get output in a list by using node.js run on a *js file defined in 'path' varriable
                  Page<Object> pages1 = new PageImpl<Object>(objectlist, pageable, objectlist.size());
                  return pages1;
              }
          
          }
          //4) write your controller
          public class PersonController {
          
              final PersonService personService;
          
              @Autowired
              PersonController( PersonService personService ){
                  this.personService = personService;
              }
          
              @GetMapping("/get") // Use of findALL() function
              Page<Person> listed( Pageable pageable){
                  Page<Person> persons = personService.listAllByPage(pageable);
                  return persons;
              } 
              @GetMapping("/spec") // Use of defined function
              Page<Object> listSpec( Pageable pageable, String path){
                  Page<Object> obj = personService.listSpecByPage(pageable, path);
                  return obj;
             } 
          
          }
          

          【讨论】:

            【解决方案11】:

            您是否尝试将存储库扩展到PagingAndSortingRepository

            public interface UserRepo extends PagingAndSortingRepository<Ticket, Integer> {
                Page<User> findAllByProgramId(Integer programId, Pageable pageable);
            }
            

            服务

            Page<User> findAllByProgramId(Integer programId, Pageable pageable);
            

            我假设您正在使用服务接口:

            【讨论】:

              【解决方案12】:

              感谢下面的代码在我的情况下工作

                  int start = pageble.getOffset();
                  int end = (start + pageble.getPageSize()) > vehicleModelsList.size() ? vehicleModelsList.size() : (start + pageble.getPageSize());
              

              【讨论】:

              • 欢迎来到 StackOverflow!这个答案与this answer 有什么不同?如果完全一样,请重新考虑您的答案(是否应该仍然在这里)并投票给已经给出的答案。
              【解决方案13】:

              reference documentation 中所述,Spring Data 存储库通过简单地声明Pageable 类型的参数来支持查询方法的分页,以确保它们只读取请求的Page 所需的数据。

              Page<User> page = findAllByProgramId(Integer programId, Pageable pageable);
              

              这将返回一个Page 对象,其页面大小/设置在您的Pageable 对象中定义。无需获取列表然后尝试从中创建页面。

              【讨论】:

              • 解决了 OP 的问题,但不是问题。假设我们有一个需要转换的数据库对象(例如 User,但我们想将包含该数据的某些子集的 UserDetails DTO 的页面发送到前端)。在这种情况下,可能需要手动创建页面。
              • OP 没有提到任何与 DTO 或转换数据相关的内容,所以我看不出它是如何回答问题的。
              猜你喜欢
              • 2011-12-06
              • 1970-01-01
              • 2022-01-03
              • 2022-08-20
              • 2022-01-05
              • 2012-06-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多