Spring Data JPA提供了Pageable
类来支持分页查询,在基本原理一课我们学习过PagingAndSortingRepository
,先来回顾一下:
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort var1); //根据某个排序获取所有数据
Page<T> findAll(Pageable var1); //根据分页信息获取某一页的数据
}
来看Page<T> findAll(Pageable var1)
这个方法,我们主要关注它的参数以及返回值。
Pageable
接口是所有分页相关信息(如pageNumber
和pageSize
)的一个抽象,Spring Data JPA能够通过Pageable
参数来生成带分页信息的SQL语句。Page
接口表示包含了分页信息的查询结果。Spring Data JPA除了会通过命名规范帮助我们生成SQL语句外,还会帮助我们处理类型为Pageable
的参数,将Pageable
参数转换成为SQL语句中的条件,同时,还会帮助我们处理类型为Page
的返回值,当发现返回值类型为Page
,Spring Data Jpa将会把数据的整体信息、当前数据的信息,分页的信息都放入到返回值中。这样,我们就能够方便的进行个性化的分页查询。
看完分页查询方法的定义后,现在让我们来尝试使用一下。
在使用分页查询之前,我们需要先实例化一个Pageable
对象。Pageable
定义了很多方法,但其核心的信息只有两个:
page
和size
)Spring Data JPA提供了PageRequest
作为Pageable
的具体实现,我们直接实例化PageRequest
对象即可:
Sort sort = new Sort(Direction.DESC, "id");
Pageable pageable = new PageRequest(page, size, sort);
return blogRepository.findAll(pageable);
上面的代码通过参数获得分页的信息,并通过Sort
以及Direction
告诉Pageable
需要通过id
逆序排列。
我们来写一个Controller展示我们的查询结果:
@RestController
@RequestMapping(value = "/blogs")
public class TestController {
@Autowired BlogRepository blogRepository;
@GetMapping
public Page<Blog> getEntryByPageable(@PageableDefault(value = 15, sort = { "id" }, direction = Sort.Direction.DESC) Pageable pageable) {
return blogRepository.findAll(pageable);
}
}
Spring Data JPA 对 Spring MVC有着很好的支持。方法的参数中直接定义一个Pageable
类型的参数,当Spring发现这个参数就会根据请求中的参数来自动生成Pageble
对象。
在浏览器中访问http://localhost:8080/blogs就能看到下列内容:
{
"content":[
{"id":123,"title":"blog122","content":"this is blog content"},
{"id":122,"title":"blog121","content":"this is blog content"},
{"id":121,"title":"blog120","content":"this is blog content"},
{"id":120,"title":"blog119","content":"this is blog content"},
{"id":119,"title":"blog118","content":"this is blog content"},
{"id":118,"title":"blog117","content":"this is blog content"},
{"id":117,"title":"blog116","content":"this is blog content"},
{"id":116,"title":"blog115","content":"this is blog content"},
{"id":115,"title":"blog114","content":"this is blog content"},
{"id":114,"title":"blog113","content":"this is blog content"},
{"id":113,"title":"blog112","content":"this is blog content"},
{"id":112,"title":"blog111","content":"this is blog content"},
{"id":111,"title":"blog110","content":"this is blog content"},
{"id":110,"title":"blog109","content":"this is blog content"},
{"id":109,"title":"blog108","content":"this is blog content"}],
"last":false,
"totalPages":9,
"totalElements":123,
"size":15,
"number":0,
"first":true,
"sort":[{
"direction":"DESC",
"property":"id",
"ignoreCase":false,
"nullHandling":"NATIVE",
"ascending":false
}],
"numberOfElements":15
}
通过查询结果,我们可以知道:
怎么样,信息是不是很丰富,代码是不是很简单,还可以通过添加参数得到不同的分页结果,例如http://localhost:8080/blogs?page=1&size=5&sort=id,desc ,快点来尝试一下Jpa的分页查询吧。
Spring Data JPA还提供了更多高级的查询功能,从命名我们就能猜测出其对应的查询条件:
User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
List<User> findFirst10ByLastname(String lastname, Sort sort);
List<User> findTop10ByLastname(String lastname, Pageable pageable);
比如,比如获取访问量排名前十的博客,可以定义类似这样的方法:
登录发表评论 登录 注册