spring jpa分页条件模糊查询
时间: 2025-07-10 13:19:06 浏览: 18
### 实现Spring JPA中的带条件分页和模糊查询
#### 方法概述
在Spring JPA中实现带条件的分页和模糊查询可以通过多种方式完成。一种常见的方式是结合`JpaSpecificationExecutor`接口来动态构建复杂的查询条件,并配合`Pageable`对象实现分页功能[^1]。
---
#### 接口设计
为了支持复杂查询,可以在Repository层让接口继承`JpaRepository`以及`JpaSpecificationExecutor`两个接口:
```java
public interface MyEntityRepository extends JpaRepository<MyEntity, Long>, JpaSpecificationExecutor<MyEntity> {
}
```
上述代码片段展示了如何扩展基本的功能以支持更高级的操作。
---
#### 动态条件与模糊匹配
对于动态条件和模糊查询的需求,可以借助`javax.persistence.criteria.CriteriaBuilder`创建灵活的查询逻辑。具体来说,在Service层编写一个方法用于构造`Specification`实例,该实例封装了所有的过滤条件。
以下是基于字段名称、操作符(如等于、大于)、以及值参数化生成规格说明的一个例子:
```java
import org.springframework.data.jpa.domain.Specification;
public static Specification<MyEntity> buildSpec(Map<String, Object> searchParams) {
return (root, query, cb) -> {
Predicate predicate = null;
for (Map.Entry<String, Object> entry : searchParams.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String && ((String)value).contains("%")) {
// 处理模糊查询
Path<String> path = root.get(key);
Predicate tempPredicate = cb.like(path.as(String.class), "%" + value.toString() + "%");
if(predicate == null){
predicate = tempPredicate;
}
else{
predicate = cb.and(predicate,tempPredicate);
}
}else{
// 添加其他类型的比较器...
Path<Object> path = root.get(key);
Predicate tempPredicate = cb.equal(path,value);
if(predicate == null){
predicate = tempPredicate;
}
else{
predicate = cb.and(predicate,tempPredicate);
}
}
}
return predicate;
};
}
```
此部分实现了根据传入的地图结构自动组装SQL WHERE子句的能力。
---
#### 执行分页查询
当准备好`Specification`之后,就可以调用带有分页选项的服务端点。下面是一个简单的服务函数演示如何组合这些组件来进行最终的数据检索:
```java
@Service
public class MyEntityService {
private final MyEntityRepository myEntityRepository;
public MyEntityService(MyEntityRepository myEntityRepository) {
this.myEntityRepository = myEntityRepository;
}
public Page<MyEntity> getEntitiesWithPaginationAndFiltering(
Map<String, Object> filters,
int page,
int size) {
Specification<MyEntity> spec = buildSpec(filters);
Pageable paging = PageRequest.of(page, size);
return myEntityRepository.findAll(spec, paging);
}
}
```
这里的关键在于将之前定义好的`buildSpec()`应用到实际数据库交互上,并指定每一页应该返回多少条记录[^2]。
---
#### 测试案例
假设我们有一个实体类叫做`Customer`,它有三个属性分别是名字(`name`)、年龄(`age`)还有地址(`address`)。如果我们想查找所有姓氏为“张”的客户并按第0页显示前5位的结果,则可如下配置请求体:
```json
{
"filters": {"name":"%张%" },
"page": 0,
"size": 5
}
```
随后调用对应API即可获取满足条件的第一批数据集合[^3]。
---
阅读全文
相关推荐


















