Spring 中 List 到 Page 的转换

我试图在春天把列表转换成页面。我已经把它用

New PageImpl (用户、可分页用户、 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);
}

这是我的用户 Repo

public interface UserRepo extends JpaRepository<User, Integer>{


public List<User> findAllByProgramId(Integer programId);

这就是我的服务

    public List<User> findAllByProgramId(Integer programId);
177401 次浏览

I had the same problem. I used subList:

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());

As indicated in the reference documentation, Spring Data repositories support pagination on query methods by simply declaring a parameter of type Pageable to make sure they're only reading the data necessary for the requested Page.

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

That would return a Page object with the page size/settings defined in your Pageable object. No need to get a list and then try to create a page out of it.

Thanks guys below code is working in my case

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

Have you tried extending your repository to PagingAndSortingRepository?

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

Service

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

I assume you are using interface to the service:

//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;
}


}
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());
}

There is a Page implementation for that:

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

This could be the solution. Sorting and pagination will work too this way:

Controller:

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);
}

Service:

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

Repository:

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

This way, we can also return different page of entity too.

You should do it like advised by the dubonzi's answer.

If you still want to use pagination for a given List use 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

If you need sorting, use another PagedListHolder constructor with a MutableSortDefinition.

Instead of returing complete array list take subblist as per your requirement. You will get 'offset' and size from 'pageable' object in request body.

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

Implemented based on @shilaimuslm comment. In this case an exception will not be thrown if the start > end in 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());

In the JHipster framework there is an interface for such things 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());
}

This is the correct answer to pagging a list

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);
}

You can use this generic function for converting List to page.

public static<T> Page<T> convertToPage(List<T> objectList, Pageable pageable){
int start = (int) pageable.getOffset();
int end = Math.min(start+pageable.getPageSize(),objectList.size());
List<T> subList = start>=end?new ArrayList<>():objectList.subList(start,end);
return new PageImpl<>(subList,pageable,objectList.size());
}