在刚开始学习的时候,在dao的定义的接口需要继承JpaRepository
要想使用Spring Data JPA,需要在pom.xml中添加以下依赖:
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.7.RELEASEversion>
<relativePath/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependencies>
如前言所说,带条件的分页查询方法是被定义在JpaSpecificationExecutor接口中的,所以这里需要继承这个接口。
/**
* @author Veggie
* @date 2019/8/14 - 14:11
*/
@Repository
public interface MessageRepository extends JpaRepository<Message, Long>,
JpaSpecificationExecutor<Message> {
}
自定义查询条件的步骤:
//自定义查询条件
Specification<Message> spec = new Specification<Message>() {
@Override
public Predicate toPredicate(Root<Message> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
//根据属性名获取查询对象的属性
Path<Message> path = root.get("receiverName");
//相当于 where receiverName = "Veggie", CriteriaBuilder接口中还有很多查询条件,建议看源码
Predicate equal = criteriaBuilder.equal(path, "Veggie");
return equal;
}
}
//进行条件查询,findAll()方法中的参数即为条件
List<Message> result = MessageRepository.findAll(spec);
当查询条件用到gt, ge, lt, le, like(分别表示>, >=, <, <=,模糊查询)时,需要表明查询对象属性的类别,如下所示:
//查询用户名以"V"开头的用户
Predicate like = criteriaBuilder.like(path.as(String.class), "V%");
排序用到的是一个Sort类,它是查询的排序选项(看源码,有介绍)
它初始化是用到的参数第一个参数:
Sort.Direction.DESC表示降序
Sort.Direction.ASC表示升序
随后的参数就是要排序的属性列表,可以有多个参数,也可以直接用List传,但是至少传入一个属性。
Sort sort = new Sort(Sort.Direction.DESC, "id");
//sort作为findAll()方法中的参数,查询得到得到的结果是经过排序的
List<Message> result = MessageRepository.findAll(sort);
分页需要设置分页参数类Pageable,初始化主要是有两个参数:第一个是查询的页码(下标从0开始),第二个是每页查询的条数,比如说结果有55条,如果每页查询10条,结果就会被分成6页。也可以添加
注意:原来用到的new PageRequest()已经过时,现在用PageRequest.of()来实现。
Page接口是封装为Spring Data Jpa 内部的page bean,它的常用方法如下:
//获取总页数
int getTotalPages();
//获取总记录数
long getTotalElements();
//获取列表数据
List<T> getContent();
分页查询的代码如下:
//设置分页参数
Pageable pageable = PageRequest.of(0,5);
//分页查询
Page<Message> page = MessageRepository.findAll(pageable);
完整的代码是以上三个知识点的集合,是带条件的分页查询,查询得到的结果按id号降序排序。
@RequestMapping(path = "/page")
public List<Message> queryPage(@RequestBody Map<String, Object> params) {
/**
* 自定义查询条件
* 1. 实现Specification接口(提供泛型;查询的对象类型)
* 2. 实现toPredicate方法(构造查询条件)
* 3. 需要借助方法参数中的两个参数(
* root:获取需要查询的对象属性
* CriteriaBuilder:构造查询条件,内部封装了很多查询条件(模糊匹配,精准匹配)
*/
Specification<Message> spec = new Specification<Message>() {
@Override
public Predicate toPredicate(Root<Message> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
Path<Message> path = root.get("receiverName");
Predicate equal = criteriaBuilder.equal(path, "Veggie");
return equal;
}
};
Integer pageNo = Integer.valueOf((String) params.get("pageNo"));
Integer pageSize = Integer.valueOf((String)params.get("pageSize"));
/**
* 添加排序Sort
* Sort.Direction.DESC表示降序
* Sort.Direction.ASC表示升序
* properties是指实体类的属性名(不是字段名)
*/
Sort sort = new Sort(Sort.Direction.ASC, "id");
/**
* 分页参数Pageable
* 参数1:查询的页码
* 参数2:每页查询的条数
* 参数3:查询结果的排序规则(可选
*/
Pageable pageable = PageRequest.of(pageNo, pageSize, sort); //原来的new PageRequest()已经过时
/**
* 分页查询
* 参数1:查询条件Specification
* 参数2:分页参数Pageable
*/
Page<Message> page = MessageRepository.findAll(spec, pageable);
return page.getContent();
}
既然都写博客了,顺带记录最近学习以及和大佬交谈的感悟: