分页和多个sorter url 参数配置:
?size=10&page=0&sort=enrollStatusCode,asc&sort=name,asc
return xxxxxService.getXxxx({
size: 10,
page: 0,
sort: ['hasSynchronize,asc', 'oid,desc']
}).$promise.then().catch();
Spring Data JPA 对于分页以及排序的查询也有着完美的支持,接下来,我们来学习如何通过 Pageable 来对数据库进行分页查询。
Spring Data JPA 中的 PagingAndSortingRepository 接口
如果要实现分页和排序功能,自己的 repository 的接口必须要继承 PagingAndSortingRepository 接口。其实Spring Data JPA 中的 JpaRespository 已经继承了该接口。
public interface JpaRepository<T, ID extends Serializable>
extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
......
}
//BlogRepository为例,直接继承了 PagingAndSortingRepository
public interface BlogRepository extends PagingAndSortingRepository<Blog, Integer> {
Page<Blog> findByDeletedFalse(Pageable pageable);
}
我们可以看到,BlogRepository 定义了这样一个方法:Page findByDeletedFalse(Pageable pageable);,我们主要关注它的参数以及返回值。
Pageable 与 Page
Pageable 是Spring Data库中定义的一个接口,该接口是所有分页相关信息的一个抽象,通过该接口,我们可以得到和分页相关所有信息(例如pageNumber、pageSize等),这样,Jpa就能够通过pageable参数来得到一个带分页信息的Sql语句。
Page类也是Spring Data提供的一个接口,该接口表示一部分数据的集合以及其相关的下一部分数据、数据总数等相关信息,通过该接口,我们可以得到数据的总体信息(数据总数、总页数…)以及当前数据的信息(当前数据的集合、当前页数等)
Spring Data Jpa 除了会通过命名规范帮助我们扩展Sql语句外,还会帮助我们处理类型为 Pageable 的参数,将 pageable 参数转换成为sql语句中的条件,同时,还会帮助我们处理类型为Page的返回值,当发现返回值类型为Page,Spring Data Jpa将会把数据的整体信息、当前数据的信息,分页的信息都放入到返回值中。这样,我们就能够方便的进行个性化的分页查询。
Pageable只是一个抽象的接口,那么,家下来我们学习如何获得pageable对象。
Pageable定义了很多方法,但其核心的信息只有两个:一是分页的信息(page、size),二是排序的信息。
通过参数生成Pageable对象
Spring Data Jpa提供了 PageRequest 的具体实现,我们只提供分页以及排序信息即可:
@RequestMapping(value = "/params", method=RequestMethod.GET)
public Page<Blog> getEntryByParams(@RequestParam(value = "page", defaultValue = "0") Integer page, @RequestParam(value = "size", defaultValue = "15") Integer size) {
Sort sort = new Sort(Direction.DESC, "id");
Pageable pageable = new PageRequest(page, size, sort);
return blogRepository.findAll(pageable);
}
在这里,我们通过参数获得分页的信息,并通过 Sort 以及 Direction 告诉 pageable 需要通过id逆序排列。这里可以看到,通过参数来得到一个 pageable 对象还是比较繁琐的,当查询的方法比较多的时候,会产生大量的重复代码。为了避免这种情况,Spring Data提供了直接生成 pageable 的方式。
直接获取Pageable对象
@RequestMapping(value = "", method=RequestMethod.GET)
public Page<Blog> getEntryByPageable(@PageableDefault(value = 15, sort = { "id" }, direction = Sort.Direction.DESC)
Pageable pageable) {
return blogRepository.findAll(pageable);
}
我们可以看到,我们只需要在方法的参数中直接定义一个pageable类型的参数,当Spring发现这个参数时,Spring会自动的根据request的参数来组装该 pageable 对象,Spring支持的request参数如下:
page,第几页,从0开始,默认为第0页
size,每一页的大小,默认为20
sort,排序相关的信息,以property,property(,ASC|DESC)的方式组织,例如sort=firstname&sort=lastname, desc表示在按firstname正序排列基础上按lastname倒序排列
这样,我们就可以通过url的参数来进行多样化、个性化的查询,而不需要为每一种情况来写不同的方法了。
通过url来定制pageable很方便,但唯一的缺点是不太美观,因此我们需要为pageable设置一个默认配置,这样很多情况下我们都能够通过一个简洁的url来获取信息了。
Spring提供了@PageableDefault帮助我们个性化的设置pageable的默认配置。例如@PageableDefault(value = 15, sort = { “id” }, direction = Sort.Direction.DESC)表示默认情况下我们按照id倒序排列,每一页的大小为15。
带查询条件的分页功能实现:
Spring data jpa通过方法的命名约束来实现,比如:
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
public interface IncidentRepo extends JpaRepository<Incident, Long> {
Page<Incident> findByProblemId(Long problemId, Pageable pageable);
}
The PagingAndSortingRepository just adds the very basic CRUD methods in pagination mode. As the reference documentation describes, you can simply add a Pageable parameter to any query method you define to achieve pagination of this query.
interface CustomerRepository implements Repository<Customer, Long> {
Page<Customer> findByLastname(String lastname, Pageable pageable);
List<Customer> findByFirstname(String firstname, Pageable pageable);
}
The first method will return a Page containing the page metadata like total elements available etc. To calculate this data it will trigger an additional count query for the query derived. The second query method returns the plain sliced result set without the count query being executed.
Java Code Examples for org.springframework.data.domain.Pageable