下面将详细讲解 JPA Specification 常用查询和排序的实现方法。
一、JPA Specification 查询实例
1. 前置条件
在使用 JPA Specification 进行查询前,需要先引入相关的依赖:
<!-- JPA规范,提供了一套标准API操作数据库 -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<!-- hibernate实现了JPA的规范、提供了一套整合的API操作数据库 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.10.Final</version>
</dependency>
<!-- spring-data-jpa整合了JPA Specification规范,用于构建通用的Repository()对象 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.4.2</version>
</dependency>
同时,需要在 Spring Boot 主类上加上如下注解进行 JPA 支持:
@SpringBootApplication
@EnableJpaRepositories
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2. 实例操作
以查询姓名为 "小明",年龄大于 18 岁的学生数据为例:
public List<Student> findStudentList() {
Specification<Student> specification = (root, query, criteriaBuilder) -> {
// root为查询的根实体对象,query为查询对象,CriteriaQuery<Student> criteriaQuery为条件查询对象
Path<String> namePath = root.get("name"); // 获取name字段的Path对象
Path<Integer> agePath = root.get("age"); // 获取age字段的Path对象
// 构建查询条件
Predicate namePredicate = criteriaBuilder.equal(namePath, "小明");
Predicate agePredicate = criteriaBuilder.greaterThan(agePath, 18);
return criteriaBuilder.and(namePredicate, agePredicate);
};
return studentRepository.findAll(specification);
}
其中,Specification 为 JPA Specification 的实现类,相当于封装了查询条件的 Lambda 表达式。通过 root、query、criteriaBuilder 等参数,可以控制查询的字段、关系、聚合等操作。
通过 Path 对象可以获取到实体类的属性字段,通过 Predicate 对象可以构建查询条件。
最后,调用 Repository 的 findAll() 方法,传入 Specification 对象即可实现查询。
3. 支持排序
在查询的同时,我们也可以支持排序。以查询姓名为 "小明",年龄大于 18 岁的学生数据,并按照年龄升序排序为例:
public List<Student> findStudentList() {
Specification<Student> specification = (root, query, criteriaBuilder) -> {
// root为查询的根实体对象,query为查询对象,CriteriaQuery<Student> criteriaQuery为条件查询对象
Path<String> namePath = root.get("name"); // 获取name字段的Path对象
Path<Integer> agePath = root.get("age"); // 获取age字段的Path对象
// 构建查询条件
Predicate namePredicate = criteriaBuilder.equal(namePath, "小明");
Predicate agePredicate = criteriaBuilder.greaterThan(agePath, 18);
return criteriaBuilder.and(namePredicate, agePredicate);
};
// 构建排序条件
Sort sort = Sort.by(Sort.Direction.ASC, "age");
return studentRepository.findAll(specification, sort);
}
代码中,通过 Sort.by() 创建了一个 Sort 对象,并传入 Direction(排序方向)和字段名称。最后将 Sort 对象传入 Repository 的 findAll() 方法,即可实现按照年龄升序排序。
二、JPA Specification 多条件查询实例
1. 前置条件
同样需要引入相关依赖和添加注解。
2. 实例操作
以查询姓名为 "小明" 或者性别为 "男",并且年龄在 18 到 25 之间的学生数据为例:
public List<Student> findStudentList() {
Specification<Student> specification = (root, query, criteriaBuilder) -> {
// root为查询的根实体对象,query为查询对象,CriteriaQuery<Student> criteriaQuery为条件查询对象
Path<String> namePath = root.get("name"); // 获取name字段的Path对象
Path<String> sexPath = root.get("sex"); // 获取sex字段的Path对象
Path<Integer> agePath = root.get("age"); // 获取age字段的Path对象
// 构建查询条件
Predicate namePredicate = criteriaBuilder.equal(namePath, "小明");
Predicate sexPredicate = criteriaBuilder.equal(sexPath, "男");
Predicate agePredicate = criteriaBuilder.between(agePath, 18, 25);
return criteriaBuilder.or(namePredicate, sexPredicate).and(agePredicate);
};
return studentRepository.findAll(specification);
}
通过 criteriaBuilder.or()
方法可以实现或者查询,传入多个 Predicate 对象即可。同时,使用 criteriaBuilder.and()
方法连接年龄查询条件,将多个条件拼接即可实现多条件查询。
3. 支持排序
在多条件查询的基础上,同样支持排序。以查询姓名为 "小明" 或者性别为 "男",并且年龄在 18 到 25 之间的学生数据,并按照年龄降序排序为例:
public List<Student> findStudentList() {
Specification<Student> specification = (root, query, criteriaBuilder) -> {
// root为查询的根实体对象,query为查询对象,CriteriaQuery<Student> criteriaQuery为条件查询对象
Path<String> namePath = root.get("name"); // 获取name字段的Path对象
Path<String> sexPath = root.get("sex"); // 获取sex字段的Path对象
Path<Integer> agePath = root.get("age"); // 获取age字段的Path对象
// 构建查询条件
Predicate namePredicate = criteriaBuilder.equal(namePath, "小明");
Predicate sexPredicate = criteriaBuilder.equal(sexPath, "男");
Predicate agePredicate = criteriaBuilder.between(agePath, 18, 25);
return criteriaBuilder.or(namePredicate, sexPredicate).and(agePredicate);
};
// 构建排序条件
Sort sort = Sort.by(Sort.Direction.DESC, "age");
return studentRepository.findAll(specification, sort);
}
代码中,通过 Sort.by() 创建了一个 Sort 对象,并传入 Direction(排序方向)和字段名称。最后将 Sort 对象传入 Repository 的 findAll() 方法,即可实现按照年龄降序排序。
至此,JPA Specification 常用查询和排序的操作就结束了。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JPA Specification常用查询+排序实例 - Python技术站