七十亿兄你好
首先来说如果使用 JPA 自带的分页查询是很简单的事你只需要在 JPA 接口方法的最后一个参数位置加上 Pageable 就可以了但是需要注意你的 JPA 接口需要继承自 PagingAndSortingRepository我的建议是直接实现 JpaRepository 接口就可以。
Pageable 不仅支持分页还支持排序在使用上非常简单例如
// 需要有分页和排序的功能
Sort sort = new Sort(
request.getOrder().equals("DESC") ? Sort.Direction.DESC : Sort.Direction.ASC,
"createTime"
);
// pageNo 从 0 开始
Pageable pageable = PageRequest.of(request.getPageNo() - 1, request.getPageSize(), sort);
只有一点你需要额外的注意就是 page 的参数从 0 开始计算这和数组中的索引是类似的。
说完了分页包含了排序再来讨论下复查条件过滤。什么叫做复杂的条件过滤呢我举个例子你有个列表页面定义了很多记录筛选条件可以按照姓名、年龄段、性别、邮箱、地址等等条件进行过滤你总不可能在 JPA 接口中写很多 or、or、or 之类的方法吧那怎么办呢
Spring Data Jpa 同样提供了类似 Hibernated 的 Criteria 的查询方式要使用这种方式只需要继承JpaSpecificationExecutor该接口提供了如下一些方法
T findOne(Specification<T> var1);
List<T> findAll(Specification<T> var1);
Page<T> findAll(Specification<T> var1, Pageable var2);
List<T> findAll(Specification<T> var1, Sort var2);
long count(Specification<T> var1);
该接口通过 Specification 来定义查询条件使用 Specification 的要点就是 CriteriaBuilder通过这个对象来创建条件之后返回一个 Predicate 对象这个对象中就有了相应的查询需求例如
new Specification<Student>() {
@Override
public Predicate toPredicate(Root<Imooc> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//root.get("address") 表示获取 address 这个字段名称, like 表示执行 like 查询, %imooc% 表示值
Predicate p1 = criteriaBuilder.like(root.get("address"), "%imooc%");
Predicate p2 = criteriaBuilder.greaterThan(root.get("id"),3);
// 将两个查询条件联合起来之后返回 Predicate 对象
return criteriaBuilder.and(p1, p2);
}
}
其中CriteriaBuilder 可以设置各种各样的查询条件几乎是 SQL 支持什么CriteriaBuilder 就支持什么可以打开源码简单看看。
最后我再强调一点吧如果你在业务逻辑中有少量的 join 需要写那么最好不要直接使用 JPA 做连接查询分开两次查询就可以如果是涉及到大量的 join最好是修改表结构冗余存储降低 join。因为 join 这种查询如果写不好最差的情况会导致请求卡死数据库造成业务瘫痪。
我是勤一致力于将这门课程的问答区打造为 Java 知识体系知识库Java 知识体系 BBS共同建造、维护这门课程我需要每一个你