Spring中List到Page的转换
Posted
技术标签:
【中文标题】Spring中List到Page的转换【英文标题】:Conversion of List to Page in Spring 【发布时间】: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 方法来说是相当长的。但我会发布存储库一个
【参考方案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 constructor 和 MutableSortDefinition。
【讨论】:
你能解释一下在这种情况下如何使用PagedListHolder
和MutableSortDefinition
吗?【参考方案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());
【讨论】:
欢迎来到 ***!这个答案与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 或转换数据相关的内容,所以我看不出它是如何回答问题的。以上是关于Spring中List到Page的转换的主要内容,如果未能解决你的问题,请参考以下文章
spring data jpa中的page对象带到jsp页面遍历问题
Spring Boot 中使用一个注解轻松将 List 转换为 Excel 下载
如何在 spring-data-rest 中将 Page<ObjectEntity> 映射到 Page<ObjectDTO>