jpa 带条件查询分页
时间: 2025-01-07 22:03:03 浏览: 40
### 如何使用 JPA 实现带条件查询的分页功能
为了实现带有条件查询的分页功能,在 `Spring Data JPA` 中可以利用 `JpaRepository` 和 `JpaSpecificationExecutor` 接口来完成此操作。通过继承这两个接口,可以在 Repository 层获得强大的 CRUD 功能以及动态构建复杂查询的能力。
#### 定义实体类
假设有一个名为 `User` 的实体类表示用户表:
```java
@Entity
public class User {
@Id
private Long id;
private String name;
private Integer age;
// getters and setters omitted for brevity
}
```
#### 创建自定义规格说明 (Specification)
在 Service 层创建一个用于封装查询逻辑的方法,该方法返回一个 `Specification<User>` 对象,这个对象可以根据传入参数动态生成 JPQL 查询语句[^1]。
```java
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
public static Specification<User> buildSpec(String userName, Integer minAge) {
return new Specification<User>() {
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
if (userName != null && !"".equals(userName)) {
predicates.add(cb.like(root.get("name"), "%" + userName + "%"));
}
if (minAge != null) {
predicates.add(cb.ge(root.<Integer>get("age"), minAge));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
}
};
}
```
#### 编写服务层业务逻辑
接下来是在 Service 类里边编写具体的服务端处理函数,这里会调用上面提到过的 `buildSpec()` 方法并将其传递给 Repository 进行实际的数据访问操作[^2]。
对于 **非分页查询** 可以这样执行:
```java
List<User> findUsersByConditions(String userName, Integer minAge){
return userRepository.findAll(buildSpec(userName,minAge));
}
```
而对于 **分页查询**, 则需引入 Pageable 参数以便控制每一页显示多少条记录及当前处于哪一页 :
```java
Page<User> findPagedUsersByConditions(String userName, Integer minAge, int pageNumber,int pageSize){
PageRequest pageRequest= PageRequest.of(pageNumber-1,pageSize);
return userRepository.findAll(buildSpec(userName,minAge),pageRequest);
}
```
上述代码片段展示了如何基于输入的名字和最小年龄作为过滤条件来进行用户的检索工作,并支持简单的分页机制。注意这里的 `pageNumber` 是从 1 开始计数的,而 Spring 默认是从 0 计算页面索引,因此需要减去 1 来调整为正确的起始位置。
阅读全文
相关推荐



















