Trivikrama
Trivikrama

Reputation: 213

Spring Custom Query with pageable

I want to to implement pagination in spring application.I know using repository we can implement pagination but we can not write our own query for data retrieve there are limited methods in repository that too there is no method accepting query class.

If we want to write our custom query to retrieve data from mongodb we have to use mongotemaplete, as i know with mongotemplate we can not implement pagination.

Is there any another way to implement pagination along with db queries. any one can help me.

Upvotes: 20

Views: 37619

Answers (7)

KneeLess
KneeLess

Reputation: 581

You can define your query using Spring's @Query annotation and then define a Pageable as the last parameter:

public interface FooRepository extends MongoRepository<Foo,String> {    
    @Query(value="{'name': ?0}")
    Page<Foo> findByMethod(String name, Pageable pageable);
}

Then, use it like so:

Page<Foo> fooPage = fooRepository.findByMethod("John", new PageRequest(0,20));

Upvotes: 21

Vasanth Umapathy
Vasanth Umapathy

Reputation: 1741

Here is the example without loading all the data in memory.

@Autowired
private MongoTemplate mongoTemplate; 

    @Override
public Page<YourClass> findAll(/* params, ... */ @NotNull Pageable pageable) {
    Query query = query(
            where("...")
            // ... your query ...
    ).with(pageable);
    Long totalCount = mongoTemplate.count(query, YourClass.class);
    List<YourClass> results = mongoTemplate.find(query.with(pageable), YourClass.class);
    Page<YourClass> resultsWithPage = PageableExecutionUtils.getPage(results, pageable, () -> totalCount);
    return resultsWithPage;
}

Upvotes: 3

WilliaGuy
WilliaGuy

Reputation: 217

Pageable pageableBase = PageRequest.of(0, request.getSize());
List <User> users = userRepository.findAllSignUpComplete(true, pageableBase);

public interface UserRepository extends PagingAndSortingRepository<User, String> {...

Upvotes: 0

abhinav kumar
abhinav kumar

Reputation: 1803

I am providing a code snippet on how we implement pagination using springboot with jpa simply using PagingAndSortingRepository which contains inbuild method for pagination.

public interface PersonRepository extends PagingAndSortingRepository<Person, Integer> {

}

  @Service
  public class PersonServiceImpl implements PersonService{
  
  @Autowired
  private PersonRepository personRepository;

  public Page<Person> listAll(int pageNumber){
   if(pageNumber>0){
  Pageable pageWithTenElements = PageRequest.of(pageNumber-1,10);
  //first param decide page and second param decide no of record

   return personRepository.findAll(pageWithTenElements);}
   else 
   return null;
  }

  }

  @RestController
  public class AppController {
  
  @Autowired
  private PersonService personService;

   @GetMapping("/page/{pageNumber}")
   public ResponseEntity<List<Person>> getPersons(@PathVariable("pageNumber") pageNumber){
   List<Person> persons = personService.listAll(pageNumber).getContent();
   ResponseEntity<SkillsTierResponse> response = 
                           new ResponseEntity<List<Person>>(persons,HttpStatus.OK);
        
        return response;
   }

  }

Upvotes: 0

d0x
d0x

Reputation: 11601

As you figured out, MongoTemplate doesn't support the complete page abstraction. Like KneeLess said you can use the @Query-Annotation to do some custom queries.

In case this isn't enough for you, can use utilize the Spring Repository PageableExecutionUtils in combination with your MongoTemplate.

For example like this:

@Override
public Page<XXX> findSophisticatedXXX(/* params, ... */ @NotNull Pageable pageable) {

    Query query = query(
            where("...")
            // ... sophisticated query ...
    ).with(pageable);

    List<XXX> list = mongoOperations.find(query, XXX.class);
    return PageableExecutionUtils.getPage(list, pageable,
              () -> mongoOperations.count((Query.of(query).limit(-1).skip(-1), XXX.class));
}

Spring Repositories are doing the same. As you can see here, they fire two queries as well.

Upvotes: 33

Jack
Jack

Reputation: 213

Just putting it out in case someone needs it.

SpringData has a method for custom query:

final Pageable pageableRequest = new PageRequest(0, 2);
Query query = new Query();
query.with(pageableRequest);

Upvotes: 13

Chazar
Chazar

Reputation: 91

By extending Spring Data PagingAndSortingRepository interface you can get some common methods such as save, find, findAll and delete and also you can add your own custom queries:

public interface Repository extends PagingAndSortingRepository<Book, ID extends Serializable> {

    // Common method
    Page<Book> findAll(Pageable pageable);

    // Custom query based on Spring Data naming convention
    Page<Book> findByNameOrDescription(String name, String description, Pageable pageable);

}

Upvotes: 6

Related Questions