JPA实现复杂条件分页查询
相信熟悉Hibernate的人对于ORM给编程带来的便利于快捷一定不陌生,相对于MyBatis等需要编写复杂的SQL语句,ORM映射为我们带来的便利显而易见。但是,在获得便利的同时,失去的便是灵活性,这里不是说Hibernate不灵活,只是针对初学者来说,要掌握灵活的技巧,需要的成本相对较高。过去的半年里,在项目中通过Spring Cloud实现了一套关于为服务的基础架构,其中在数据持久层采用的是Spring Data JPA,对于曾经用过Hibernate的人来说,选择JPA会十分容易上手,因为语法一切都是那么熟悉。但是,在涉及到复杂的查询的时候,尤其是多条件查询的时候,如果通过命名方式实现,长长的方法名将是代码显得十分的不优雅。这个时候,大多数人会选择使用NativeQuery,通过编写SQL语句来实现,这种方式导致的结果就是项目代码中遍地是SQL,随着时间的推移,项目已经失去了使用JPA的初衷。能否有一种方式,在保障JPQL的风格里完成这种复杂的查询呢?这里介绍一种简单的方式:JpaSpecificationExecutor
JpaSpecificationExecutor不属于JpaRepository体系,它允许自定义查询条件实现查询。通过源码可以发现,JpaSpecificationExecutor提供了如下几个方法:
public interface JpaSpecificationExecutor<T> {
T findOne(Specification<T> spec);
List<T> findAll(Specification<T> spec);
Page<T> findAll(Specification<T> spec, Pageable pageable);
List<T> findAll(Specification<T> spec, Sort sort);
long count(Specification<T> spec);
}
其中,Page<T> findAll(Specification<T> spec, Pageable pageable)是不是看起来很熟悉,因为在JpaRepository我们用的十分常见,只不过这里的入参不同,Pageable提供了排序分页的功能,Specification允许我们自定义查询条件,继续进入源码:
public interface Specification<T> {
Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
}
没错,这个接口提供了唯一方法toPredicate,通过该方法构造出一个复杂查询条件。Root代表的是实体,CriteriaBuilder是条件构造器,通过该方法,我们构造出复杂的查询条件并返回,JPA便会自动的处理转换查询。下面以一个小demo描述使用JpaSpecificationExecutor实现复杂查询的步骤:
1、DAO层继承JpaSpecificationExecutor接口(当然,如果需要JpaRepository相关方法,同时继承即可)
@Component
public interface SpeciRepository extends JpaSpecificationExecutor<TestVO>,JpaRepository<TestVO, Long>{
}
2、Service构造查询条件,并调用DAO层
@Service
@Transactional
public class MySpeciServiceImpl implements MySpeciService {
@Autowired private SpeciRepository speciRepository;
@Override public Page<TestVO> findByPageAndParams(final TestVO param, int pageNumber,int pageSize) {
Pageable pageable=new PageRequest(pageNumber, pageSize); //分页信息
Specification<TestVO> spec = new Specification<TestVO>() { //查询条件构造
@Override public Predicate toPredicate(Root<TestVO> root, CriteriaQuery<?> query,CriteriaBuilder cb) {
Path<String> name = root.get("name");
Path<Integer> age = root.get("age");
Predicate p1 = cb.like(name, "%"+param.getName()+"%");
Predicate p2 = cb.lt(age, param.getAge());
Predicate p = cb.and(p1, p2);
return p;
}
};
return speciRepository.findAll(spec, pageable);
}
}
通过以上两个步骤,就能实现一个基本的复杂分页查询,其实很简单。其中的关键点就是查询条件的构造,可以通过CriteriaBuilder提供的相关谓词进行组装。详细用法这里不累述,有兴趣或有需要可自行baidu。
JPA实现复杂条件分页查询的更多相关文章
- springboot jpa mongodb 多条件分页查询
public Page<Recorded> getRecordeds(Integer page, Integer size, Recorded recorded) { if (page&l ...
- asp.net mvc多条件+分页查询解决方案
开发环境vs2010 css:bootstrap js:jquery bootstrap paginator 原先只是想做个mvc的分页,但是一般的数据展现都需要检索条件,而且是多个条件,所以就变成了 ...
- 【java】spring-data-jpa 集成hibernate实现多条件分页查询
初次接触spring-data-jpa,实现多条件分页查询. 基础环境 Spring Boot+spring-data-jpa+hibernate+mysql 1.接口 要继承这个接口,这个接口提供了 ...
- thinkphp 带条件分页查询
thinkphp 带条件分页查询:form表单传值时候,method='get'. 用 get 传值
- 项目一:第四天 1、快递员的条件分页查询-noSession,条件查询 2、快递员删除(逻辑删除) 3、基于Apache POI实现批量导入区域数据 a)Jquery OCUpload上传文件插件使用 b)Apache POI读取excel文件数据
1. 快递员的条件分页查询-noSession,条件查询 2. 快递员删除(逻辑删除) 3. 基于Apache POI实现批量导入区域数据 a) Jquery OCUpload上传文件插件使用 b) ...
- ASPNETCOREAPI 跨域处理 SQL 语句拼接 多条件分页查询 ASPNET CORE 核心 通过依赖注入(注入服务)
ASPNETCOREAPI 跨域处理 AspNetCoreApi 跨域处理 如果咱们有处理过MV5 跨域问题这个问题也不大. (1)为什么会出现跨域问题: 浏览器安全限制了前端脚本跨站点的访问资源, ...
- JPA分页查询与条件分页查询
情有独钟的JPA 平时在写一些小项目时,比较喜欢引用 Spring Data Jpa,其实还是图他写代码快~在日常的开发工作中,分页列表查询基本是随处可见,下面一起看一下如何使用 jpa 进行多条件查 ...
- jpa自定义条件分页查询
主要依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp ...
- 【spring data jpa】带有条件的查询后分页和不带条件查询后分页实现
一.不带有动态条件的查询 分页的实现 实例代码: controller:返回的是Page<>对象 @Controller @RequestMapping(value = "/eg ...
随机推荐
- 接口以及 LeetCode 每日一题
1 接口 1.1 接口的概念 接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心类内方法的实现细节,只是规定这批类里面必须提供某些方法.所以接口体现的是规范和实现分离的设计哲 ...
- 设计模式之结构类模式PK
结构类模式包括: 适配器模式 桥梁模式 组合模式 装饰模式 门面模式 享元模式 代理模式 结构类模式着重于如何建立一个软件结构 为什么叫结构类模式呢? 因为他们都是通过组合类或对象产生更大结构以适应更 ...
- 自学WEB前端到什么程度才能就业
做过多年web前端从业者,回答下这个问题 首先,这个问题主要问:自学web前端技术,如果才能找到一份web前端的工作.按照现在的招聘标准来看,无论你去哪个公司面试,你只需要满足他们公司的需求就可以. ...
- SAP MM 预留单据的历史修改记录?
SAP MM 预留单据的历史修改记录? 在笔者眼里,SAP系统是一个高度严谨的软件系统.用户在SAP系统里的相关操作,系统都会做记录.用户对于系统的相关单据的增删改,SAP系统都有保留change h ...
- C# 接口《通俗解释》
接口 为什么要用接口?好处在哪里? 如果你的工作是一个修水管的,一天客户找上你让你帮装水管,但是有个要求,就是客户喜欢管子是三角形的. 你立马买了三角形的水管回来,在墙上弄个三角形的口子,客户付了钱, ...
- 新DevOps八荣八耻
昀哥 20181001以随时可扩容可缩容可重启可切换机房流量为荣,以不能迁移为耻. 以可配置为荣,以硬编码为耻. 以系统互备为荣,以系统单点为耻. 以交付时有监控报警为荣,以交付裸奔系统为耻. 以无状 ...
- 第1章 程序设计和C语言
1.1什么是计算机程序 程序,就是一组计算机能识别和执行的指令.每一条指令使计算机执行特定的操作.只要让计算机执行这个程序,计算机就会“自动地”执行各条指令,有条不紊地进行工作. 1.2什么是计算机语 ...
- Fescar(Seata)-Springcloud流程分析-2阶段
上文我们分析了fescar的一阶段执行过程.在一阶段中,服务起始方发起全局事务并注册到TC.在调用协同服务时,协同服务的事务分支事务会先完成阶段一的事务提交或回滚,并生成事务回滚的undo_log日志 ...
- spring boot 集成 zookeeper 搭建微服务架构
PRC原理 RPC 远程过程调用(Remote Procedure Call) 一般用来实现部署在不同机器上的系统之间的方法调用,使得程序能够像访问本地系统资源一样,通过网络传输去访问远程系统资源,R ...
- 内核中 EXPORT_SYMBOL 标志分析
内核版本:Linux-4.19 1. EXPORT_SYMBOL 的作用: EXPORT_SYMBOL 定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在其它内核模块中直接调用,即使用 E ...