[转] Spring Data JPA Tutorial: Pagination
2016-01-25 10:54
726 查看
http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-seven-pagination/
spring data, spring data jpa, Spring Framework
31
Facebook
Twitter
Google+
LinkedIn
My Spring Data JPA tutorial has taught us how we can create database queries and sort our query results with Spring Data JPA.
We have also implemented a search function that ignores case and returns todo entries whose title or description contains the given search term. This search function sorts the returned todo entries in ascending order by using the title of the returned todo entry.
However, we are not done yet. Our example application has one serious flaw:
It returns all todo entries that are found from the database, and this is a performance problem.
This blog post helps us to eliminate this flaw. Let’s get started.
Additional Reading:
If you are not familiar with Spring Data JPA, you should read the following blog posts before you continue reading this blog post:
Spring Data JPA Tutorial: Introduction provides a quick introduction to Spring Data JPA and gives an overview of the Spring Data repository interfaces.
Spring Data JPA Tutorial: Getting the Required Dependencies describes how you can get the required dependencies.
Spring Data JPA Tutorial: Configuration describes how you can configure the persistence layer of a Spring application that uses Spring Data JPA.
Spring Data JPA Tutorial: Introduction to Query Methods describes how you can pass method parameters to your query methods and identifies the “legal” return values of Spring Data JPA query methods.
Spring Data JPA Tutorial: Creating Database Queries From Method Names describes how you can create database queries from the method names of your query methods.
Spring Data JPA Tutorial: Creating Database Queries With the @Query Annotationdescribes how you can create database queries by annotating your query methods with the@Query annotation.
Spring Data JPA Tutorial: Creating Database Queries With Named Queries describes how you can create database queries by using named queries.
Spring Data JPA Tutorial: Creating Database Queries With the JPA Criteria API describes how you can create dynamic queries by using the JPA Criteria API.
Spring Data JPA Tutorial: Creating Database Queries With Querydsl describes how you can create dynamic database queries by using Querydsl.
Spring Data JPA Tutorial: Sorting describes how you can sort your query results.
Obtain the Pageable object that specifies the information of the requested page.
Pass the Pageable object forward to the correct repository method as a method parameter.
Let’s start by finding out how we can obtain the Pageable object.
We can create it manually.
We can use Spring Data web support.
Let’s start by creating the Pageable object manually.
The source code of the RepositoryTodoSearchService class, which uses this method, looks as follows:
The following examples demonstrate how we can implement the private createPageRequest() method:
Example 1:
If we want to get the first page by using page size 10, we have to create the Pageable object by using the following code:
Example 2:
We have to sort the query results in ascending order by using the values of the title and descriptionfields. If we want to get the second page by using page size 10, we have to create the Pageable object by using the following code:
Example 3:
We have to sort the query results in descending order by using the value of the description field and in ascending order by using the value of the title field. If we want to get the second page by using page size 10, we have to create the Pageable object by using the following code:
Additional Reading:
The Javadoc of the Pageable interface
The Javadoc of the PageRequest class
The Javadoc of the Page interface
The Javadoc of the Sort class.
Let’s find out how we can obtain Pageable objects by using Spring Data web support.
This registers two HandlerMethodArgumentResolver objects that are described in the following:
The SortHandlerMethodArgumentResolver can extract sorting information from the request or from the @SortDefault annotation.
The PageableHandlerMethodArgumentResolver extracts the information of the requested page from the request.
We can now specify the information of the requested page and configure the sorting options of the invoked database query by setting the values of the following request parameters:
The page request parameter specifies the page number of the requested page. The number of the first page is 0 and the default value of this request parameter is 0 as well.
The size request parameter specifies the size of the requested page. The default value of this request parameter is 20.
The sort request parameter specifies the sorting options of the invoked query. The reference documentation of Spring Data JPA describes the content of this request parameter as follows:“Properties that should be sorted by in the format property,property(,ASC|DESC). Default sort direction is ascending. Use multiple sort parameters if you want to switch directions, e.g. ?sort=firstname&sort=lastname,asc.”
After we have enabled Spring Data web support, we can inject Pageable objects into controller handler methods. The source code of the TodoSearchController class, which utilizes Spring Data web support, looks as follows:
Additional Reading:
Spring Data JPA Reference Documentation: 3.7.1 Web Support
The Javadoc of the @EnableSpringDataWebSupport annotation
The Javadoc of the SortHandlerMethodArgumentResolver class
The Javadoc of the @SortDefault annotation
The Javadoc of the PageableHandlerMethodArgumentResolver class
The TodoSearchController gets the information of the returned todo entries from theTodoSearchService object. The RepositoryTodoSearchService class implements theTodoSearchService interface, and its findBySearchTerm() method simply passes the search term and the Pageable object forward to the invoked repository method.
The source code of the RepositoryTodoSearchService class looks as follows:
Let’s move on and find out how we can paginate our query results by using Pageable objects.
Let’s start by finding out how we can paginate all entities found from the database.
First, if we created our repository interface by extending the CrudRepository interface, we have to modify it to extend only the PagingAndSortingRepository interface.
The relevant part of our repository interface looks as follows:
Additional Reading:
The Javadoc of the PagingAndSortingRepository interface
The PagingAndSortingRepository interface declares one method which we can use when we want to paginate the query results of a query that fetches all entities from the database:
The Page<T> findAll(Pageable pageRequest) method returns a page of entities that fulfill the restrictions specified by the Pageable object.
In other words, if we want to paginate the query results of a database query that fetches all entities from the database, we have to use the Page<T> findAll(Pageable pageRequest) method instead of theIterable<T> findAll() method.
Second, if we created our repository interface by extending the Repository interface, we can declare the Page<T> findAll(Pageable pageRequest) method in our repository interface.
The relevant part of our repository interface looks as follows:
We can now get a specific page by invoking the Page<T> findAll(Pageable pageRequest) method and passing the Pageable object as a method parameter.
Additional Reading:
Spring Data JPA Tutorial: CRUD
Let’s find out how we can paginate the query results of database queries that use the query generation from the method name strategy.
Remove the sorting logic from the method name.
Add a new method parameter (Pageable object) to the query method.
Decide the returned type. We can return List<T>, Slice<T>, or Page<T> objects.
Because the search function of our example application is case-insensitive and it returns todo entries whose title or description contains the given search term, the source code of our repository interface looks as follows:
Additional Reading:
Spring Data JPA Tutorial: Creating Database Queries From Method Names
The Javadoc of the Pageable interface
The Javadoc of the Page interface
The Javadoc of the Slice interface
Let’s move on and find out how we can paginate the query results of named queries that use JPQL.
Specify the sorting logic in the JPQL query.
Add a new method parameter (Pageable object) to the query method.
Decide the returned type. We can return List<T>, Slice<T>, or Page<T> objects.
If we want to paginate the query results of the named query called: Todo.findBySearchTermNamed, the source code of our repository interface looks as follows:
We must remember two things when we are paginating the query results of named queries:
If we want to paginate and sort the query results of named queries that use JPQL, we must specify the sorting logic in the JPQL query.
We cannot paginate the query results of native named queries because there is no reliable way to manipulate SQL queries.
Additional Reading:
Spring Data JPA Tutorial: Creating Database Queries With Named Queries
The Javadoc of the Pageable interface
The Javadoc of the Page interface
The Javadoc of the Slice interface
Let’s move on and find out how we can paginate the query results of JPQL queries that are created by using the @Query annotation.
Remove the sorting logic from the JPQL query.
Add a new method parameter (Pageable object) to the query method.
Decide the returned type. We can return List<T>, Slice<T>, or Page<T> objects.
Because the search function of our example application is case-insensitive and it returns todo entries whose title or description contains the given search term, the source code of our repository interface looks as follows:
We cannot paginate the query results of native queries that use the @Query annotation because there is no reliable way to manipulate SQL queries.
Additional Reading:
Spring Data JPA Tutorial: Creating Database Queries With the @Query Annotation
The Javadoc of the Pageable interface
The Javadoc of the Page interface
The Javadoc of the Slice interface
Let’s find out how we can paginate the query results of JPA criteria queries.
The Page<T> findAll(Specification<T> spec, Pageable pageRequest) method returns a page of entities that match the Specification object and fulfill the restrictions specified by the Pageableobject.
In other words, we can paginate the query results of JPA criteria queries by using the Page<T> findAll(Specification<T> spec, Pageable pageRequest) method instead of the List<T> findAll(Specification<T> spec) method.
The source code of the RepositoryTodoSearchService class, which paginates our query results by using the Pageable object, looks as follows:
Additional Reading:
Spring Data JPA Tutorial: Creating Database Queries With the JPA Criteria API
The Javadoc of the JpaSpecificationExecutor interface
The Javadoc of the Pageable interface
The Javadoc of the Page interface
Let’s find out how we can paginate the query results of database queries that are created by using Querydsl.
The Page<T> findAll(Predicate predicate, Pageable pageRequest) method returns a page of entities that match the Predicate object and fulfill the restrictions specified by the Pageable object.
In other words, we can paginate the query results of Querydsl queries by using the Page<T> findAll(Predicate predicate, Pageable pageRequest) method instead of the List<T> findAll(Predicate predicate) method.
The source code of the RepositoryTodoSearchService class, which paginates our query results by using the Pageable object, looks as follows:
Additional Reading:
Spring Data JPA Tutorial: Creating Database Queries With Querydsl
The Javadoc of the QueryDslPredicateExecutor interface
The Javadoc of the Pageable interface
The Javadoc of the Page interface
Let’s move on and summarize what we learned from this blog post.
We can create Pageable objects manually or obtain them by using Spring Data web support.
We can configure Spring Data web support by annotating our application context configuration class with @EnableSpringDataWebSupport annotation.
We can paginate the query results of query methods, JPA criteria queries, and Querydsl queries by using the Pageable object.
We cannot paginate the query results of SQL queries by using the Pageable object because there is no reliable way to manipulate existing SQL queries.
If we want to paginate the query results of a named query that uses JPQL, we have to add the sorting logic into the JPQL query.
The next part of this tutorial describes how we can add the creation and modification time fields into our entities by using the auditing infrastructure of Spring Data JPA.
P.S. You can get the example applications of this blog post from Github: query methods, JPA Criteria API, and Querydsl.
If you want to learn how to use Spring Data JPA, you should read my Spring Data JPA tutorial.
Spring Data JPA Tutorial: Pagination
Petri Kainulainen April 23, 201256 commentsspring data, spring data jpa, Spring Framework
31
Google+
My Spring Data JPA tutorial has taught us how we can create database queries and sort our query results with Spring Data JPA.
We have also implemented a search function that ignores case and returns todo entries whose title or description contains the given search term. This search function sorts the returned todo entries in ascending order by using the title of the returned todo entry.
However, we are not done yet. Our example application has one serious flaw:
It returns all todo entries that are found from the database, and this is a performance problem.
This blog post helps us to eliminate this flaw. Let’s get started.
Additional Reading:
If you are not familiar with Spring Data JPA, you should read the following blog posts before you continue reading this blog post:
Spring Data JPA Tutorial: Introduction provides a quick introduction to Spring Data JPA and gives an overview of the Spring Data repository interfaces.
Spring Data JPA Tutorial: Getting the Required Dependencies describes how you can get the required dependencies.
Spring Data JPA Tutorial: Configuration describes how you can configure the persistence layer of a Spring application that uses Spring Data JPA.
Spring Data JPA Tutorial: Introduction to Query Methods describes how you can pass method parameters to your query methods and identifies the “legal” return values of Spring Data JPA query methods.
Spring Data JPA Tutorial: Creating Database Queries From Method Names describes how you can create database queries from the method names of your query methods.
Spring Data JPA Tutorial: Creating Database Queries With the @Query Annotationdescribes how you can create database queries by annotating your query methods with the@Query annotation.
Spring Data JPA Tutorial: Creating Database Queries With Named Queries describes how you can create database queries by using named queries.
Spring Data JPA Tutorial: Creating Database Queries With the JPA Criteria API describes how you can create dynamic queries by using the JPA Criteria API.
Spring Data JPA Tutorial: Creating Database Queries With Querydsl describes how you can create dynamic database queries by using Querydsl.
Spring Data JPA Tutorial: Sorting describes how you can sort your query results.
Paginating the Query Results of Our Database Queries
We can paginate the query results of our database queries by following these steps:Obtain the Pageable object that specifies the information of the requested page.
Pass the Pageable object forward to the correct repository method as a method parameter.
Let’s start by finding out how we can obtain the Pageable object.
Obtaining the Pageable Object
We can obtain the Pageable object by using these two methods:We can create it manually.
We can use Spring Data web support.
Let’s start by creating the Pageable object manually.
Creating the Pageable Object Manually
If we want create the Pageable object manually, the service class (or other component) that wants to paginate the query results, which are returned by a Spring Data JPA repository, must create thePageable object and pass it forward to the invoked repository method.The source code of the RepositoryTodoSearchService class, which uses this method, looks as follows:
Example 1:
If we want to get the first page by using page size 10, we have to create the Pageable object by using the following code:
We have to sort the query results in ascending order by using the values of the title and descriptionfields. If we want to get the second page by using page size 10, we have to create the Pageable object by using the following code:
We have to sort the query results in descending order by using the value of the description field and in ascending order by using the value of the title field. If we want to get the second page by using page size 10, we have to create the Pageable object by using the following code:
The Javadoc of the Pageable interface
The Javadoc of the PageRequest class
The Javadoc of the Page interface
The Javadoc of the Sort class.
Let’s find out how we can obtain Pageable objects by using Spring Data web support.
Using Spring Data Web Support
We can enable Spring Data web support by annotating our application context configuration class with the @EnableSpringDataWebSupport annotation. The relevant part of the PersistenceContext class, which configures the persistence layer of our example application, looks as follows:The SortHandlerMethodArgumentResolver can extract sorting information from the request or from the @SortDefault annotation.
The PageableHandlerMethodArgumentResolver extracts the information of the requested page from the request.
We can now specify the information of the requested page and configure the sorting options of the invoked database query by setting the values of the following request parameters:
The page request parameter specifies the page number of the requested page. The number of the first page is 0 and the default value of this request parameter is 0 as well.
The size request parameter specifies the size of the requested page. The default value of this request parameter is 20.
The sort request parameter specifies the sorting options of the invoked query. The reference documentation of Spring Data JPA describes the content of this request parameter as follows:“Properties that should be sorted by in the format property,property(,ASC|DESC). Default sort direction is ascending. Use multiple sort parameters if you want to switch directions, e.g. ?sort=firstname&sort=lastname,asc.”
After we have enabled Spring Data web support, we can inject Pageable objects into controller handler methods. The source code of the TodoSearchController class, which utilizes Spring Data web support, looks as follows:
Spring Data JPA Reference Documentation: 3.7.1 Web Support
The Javadoc of the @EnableSpringDataWebSupport annotation
The Javadoc of the SortHandlerMethodArgumentResolver class
The Javadoc of the @SortDefault annotation
The Javadoc of the PageableHandlerMethodArgumentResolver class
The TodoSearchController gets the information of the returned todo entries from theTodoSearchService object. The RepositoryTodoSearchService class implements theTodoSearchService interface, and its findBySearchTerm() method simply passes the search term and the Pageable object forward to the invoked repository method.
The source code of the RepositoryTodoSearchService class looks as follows:
Paginating Query Results With the Pageable Object
After we have created the Pageable object manually or obtained it by using Spring Data web support, we have to create the database query that paginates its query results by using the Pageable object.Let’s start by finding out how we can paginate all entities found from the database.
Paginating All Entities
If we want to paginate all entities found from the database, we can use one of the following methods:First, if we created our repository interface by extending the CrudRepository interface, we have to modify it to extend only the PagingAndSortingRepository interface.
The relevant part of our repository interface looks as follows:
The Javadoc of the PagingAndSortingRepository interface
The PagingAndSortingRepository interface declares one method which we can use when we want to paginate the query results of a query that fetches all entities from the database:
The Page<T> findAll(Pageable pageRequest) method returns a page of entities that fulfill the restrictions specified by the Pageable object.
In other words, if we want to paginate the query results of a database query that fetches all entities from the database, we have to use the Page<T> findAll(Pageable pageRequest) method instead of theIterable<T> findAll() method.
Second, if we created our repository interface by extending the Repository interface, we can declare the Page<T> findAll(Pageable pageRequest) method in our repository interface.
The relevant part of our repository interface looks as follows:
Additional Reading:
Spring Data JPA Tutorial: CRUD
Let’s find out how we can paginate the query results of database queries that use the query generation from the method name strategy.
Paginating the Query Results of Queries That Use the Query Generation From the Method Name Strategy
If we create our database queries from the method name of our query method, we can paginate the query results by following these steps:Remove the sorting logic from the method name.
Add a new method parameter (Pageable object) to the query method.
Decide the returned type. We can return List<T>, Slice<T>, or Page<T> objects.
Because the search function of our example application is case-insensitive and it returns todo entries whose title or description contains the given search term, the source code of our repository interface looks as follows:
Spring Data JPA Tutorial: Creating Database Queries From Method Names
The Javadoc of the Pageable interface
The Javadoc of the Page interface
The Javadoc of the Slice interface
Let’s move on and find out how we can paginate the query results of named queries that use JPQL.
Paginating the Query Results of Named Queries That Use JPQL
We can paginate the query results of named queries that use JPQL by following these steps:Specify the sorting logic in the JPQL query.
Add a new method parameter (Pageable object) to the query method.
Decide the returned type. We can return List<T>, Slice<T>, or Page<T> objects.
If we want to paginate the query results of the named query called: Todo.findBySearchTermNamed, the source code of our repository interface looks as follows:
If we want to paginate and sort the query results of named queries that use JPQL, we must specify the sorting logic in the JPQL query.
We cannot paginate the query results of native named queries because there is no reliable way to manipulate SQL queries.
Additional Reading:
Spring Data JPA Tutorial: Creating Database Queries With Named Queries
The Javadoc of the Pageable interface
The Javadoc of the Page interface
The Javadoc of the Slice interface
Let’s move on and find out how we can paginate the query results of JPQL queries that are created by using the @Query annotation.
Paginating the Query Results of JPQL Queries That Use the @Query Annotation
If we create our JPQL queries by using the @Query annotation, we can paginate the query results by following these steps:Remove the sorting logic from the JPQL query.
Add a new method parameter (Pageable object) to the query method.
Decide the returned type. We can return List<T>, Slice<T>, or Page<T> objects.
Because the search function of our example application is case-insensitive and it returns todo entries whose title or description contains the given search term, the source code of our repository interface looks as follows:
Additional Reading:
Spring Data JPA Tutorial: Creating Database Queries With the @Query Annotation
The Javadoc of the Pageable interface
The Javadoc of the Page interface
The Javadoc of the Slice interface
Let’s find out how we can paginate the query results of JPA criteria queries.
Paginating the Query Results of JPA Criteria Queries
If we create our database queries by using the JPA Criteria API, our repository interface must extend the JpaSpecificationExecutor<T> interface. This interface declares one method that we can use when we want to paginate the query results of JPA criteria queries:The Page<T> findAll(Specification<T> spec, Pageable pageRequest) method returns a page of entities that match the Specification object and fulfill the restrictions specified by the Pageableobject.
In other words, we can paginate the query results of JPA criteria queries by using the Page<T> findAll(Specification<T> spec, Pageable pageRequest) method instead of the List<T> findAll(Specification<T> spec) method.
The source code of the RepositoryTodoSearchService class, which paginates our query results by using the Pageable object, looks as follows:
Spring Data JPA Tutorial: Creating Database Queries With the JPA Criteria API
The Javadoc of the JpaSpecificationExecutor interface
The Javadoc of the Pageable interface
The Javadoc of the Page interface
Let’s find out how we can paginate the query results of database queries that are created by using Querydsl.
Paginating the Query Results of Querydsl Queries
If we create our database queries by using Querydsl, our repository interface must extend theQueryDslPredicateExecutor<T> interface. This interface declares one method that we can use when we want to paginate the query results of database queries that use Querydsl:The Page<T> findAll(Predicate predicate, Pageable pageRequest) method returns a page of entities that match the Predicate object and fulfill the restrictions specified by the Pageable object.
In other words, we can paginate the query results of Querydsl queries by using the Page<T> findAll(Predicate predicate, Pageable pageRequest) method instead of the List<T> findAll(Predicate predicate) method.
The source code of the RepositoryTodoSearchService class, which paginates our query results by using the Pageable object, looks as follows:
Spring Data JPA Tutorial: Creating Database Queries With Querydsl
The Javadoc of the QueryDslPredicateExecutor interface
The Javadoc of the Pageable interface
The Javadoc of the Page interface
Let’s move on and summarize what we learned from this blog post.
Summary
This blog post has taught us five things:We can create Pageable objects manually or obtain them by using Spring Data web support.
We can configure Spring Data web support by annotating our application context configuration class with @EnableSpringDataWebSupport annotation.
We can paginate the query results of query methods, JPA criteria queries, and Querydsl queries by using the Pageable object.
We cannot paginate the query results of SQL queries by using the Pageable object because there is no reliable way to manipulate existing SQL queries.
If we want to paginate the query results of a named query that uses JPQL, we have to add the sorting logic into the JPQL query.
The next part of this tutorial describes how we can add the creation and modification time fields into our entities by using the auditing infrastructure of Spring Data JPA.
P.S. You can get the example applications of this blog post from Github: query methods, JPA Criteria API, and Querydsl.
If you want to learn how to use Spring Data JPA, you should read my Spring Data JPA tutorial.
相关文章推荐
- 第一个Java Rest服务
- Intellij Idea 创建JavaWeb项目
- java 回调的同步回调和异步回调
- java String、Data、Calendar时间转化
- 【系统通信:RxJava】RxJava开篇
- Java学习初步(1)
- 关于java ssh找不到驱动的问题
- Java调用Runtime.getRuntime().exec(commandStr)来调用cmd执行指令
- IntelliJ IDEA像Eclipse一样打开多个项目
- Java线程池的分析和使用
- 《JAVA与模式》之模板方法模式
- 解决Android Studio 或eclipse运行时出现Duplicate files copied in APK main/AndroidManifest.xml
- springMvc和shiro整合,shiro的realm不能自动注入的问题
- spring 简单入门实例
- 使用Spring注解注入属性
- JavaSE-异常
- Windows Builder(图形化界面的利器)For Eclipse 3.7
- java中的单例模式与doublecheck
- 在Spring中使用Hessian Remoting技术
- java提高篇(十六)-----异常(一)