spring data jpa实现多条件查询(分页和不分页)
目前的spring data jpa已经帮我们干了CRUD的大部分活了,但如果有些活它干不了(CrudRepository接口中没定义),那么只能由我们自己干了。这里要说的就是在它的框架里,如何实现自己定制的多条件查询。下面以我的例子说明一下:业务场景是我现在有张订单表,我想要支持根据订单状态、订单当前处理人和订单日期的起始和结束时间这几个条件一起查询。
先看分页的,目前spring data jpa给我们做分页的Repository是PagingAndSortingRepository,但它满足不了自定义查询条件,只能另选JpaRepository。那么不分页的Repository呢?其实还是它。接下来看怎么实现:
Repository:
import com.crocodile.springboot.model.Flow;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; public interface FlowRepository extends JpaRepository<Flow, Long> {
Long count(Specification<Flow> specification); Page<Flow> findAll(Specification<Flow> specification, Pageable pageable); List<Flow> findAll(Specification<Flow> specification); }
Service:
/**
* 获取结果集
*
* @param status
* @param pageNo
* @param pageSize
* @param userName
* @param createTimeStart
* @param createTimeEnd
* @return
*/
public List<Flow> queryFlows(int pageNo, int pageSize, String status, String userName, Date createTimeStart, Date createTimeEnd) {
List<Flow> result = null; // 构造自定义查询条件
Specification<Flow> queryCondition = new Specification<Flow>() {
@Override
public Predicate toPredicate(Root<Flow> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicateList = new ArrayList<>();
if (userName != null) {
predicateList.add(criteriaBuilder.equal(root.get("currentOperator"), userName));
}
if (status != null) {
predicateList.add(criteriaBuilder.equal(root.get("status"), status));
}
if (createTimeStart != null && createTimeEnd != null) {
predicateList.add(criteriaBuilder.between(root.get("createTime"), createTimeStart, createTimeEnd));
}
return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
}
}; // 分页和不分页,这里按起始页和每页展示条数为0时默认为不分页,分页的话按创建时间降序
try {
if (pageNo == 0 && pageSize == 0) {
result = flowRepository.findAll(queryCondition);
} else {
result = flowRepository.findAll(queryCondition, PageRequest.of(pageNo - 1, pageSize, Sort.by(Sort.Direction.DESC, "createTime"))).getContent();
}
} catch (Exception e) {
LOGGER.error("--queryFlowByCondition-- error : ", e);
} return result;
}
上面我们可以看到,套路很简单,就是两板斧:先通过Specification对象定义好自定义的多查询条件,我这里的条件是当传了当前用户时,那么将它加入到查询条件中,不传该参数自然就不加,同理,传了订单状态的话那是通过相等来判断,最后,如果传了起始和结束时间,通过between来查在起始和结束之间的数据;第二板斧调用我们在Repository中定义好的findAll方法,如果分页就用带Pageable分页对象参数的方法,不分页不带该参数即可。
如果你的自定义查询条件里需要模糊查询,比如我有个订单ID要支持模糊查询,也很简单:
if (orderId!= null) {
predicateList.add(criteriaBuilder.like(root.get("orderId"), "%" + orderId+ "%"));}
最后我们看回到FlowRepository的第一个方法count,它是返回不分页的多查询的总记录数的,套路也是一样的:
/**
* 查记录数
*
* @param status
* @param userName
* @param createTimeStart
* @param createTimeEnd
* @return
*/
public Long getCounts(String status, String userName, Date createTimeStart, Date createTimeEnd) {
Long total = 0L;
Specification<Flow> countCondition = new Specification<Flow>() {
@Override
public Predicate toPredicate(Root<Flow> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicateList = new ArrayList<>();
if (userName != null) {
predicateList.add(criteriaBuilder.equal(root.get("currentOperator"), userName));
}
if (status != null) {
predicateList.add(criteriaBuilder.equal(root.get("status"), status));
}
if (createTimeStart != null && createTimeEnd != null) {
predicateList.add(criteriaBuilder.between(root.get("createTime"), createTimeStart, createTimeEnd));
}
return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
}
}; try {
total = flowRepository.count(countCondition);
} catch (Exception e) {
LOGGER.error("--getCountsByCondition-- error: ", e);
}
return total;
}
spring data jpa实现多条件查询(分页和不分页)的更多相关文章
- Spring MVC和Spring Data JPA之按条件查询和分页(kkpaper分页组件)
推荐视频:尚硅谷Spring Data JPA视频教程,一学就会,百度一下就有, 后台代码:在DAO层继承Spring Data JPA的PagingAndSortingRepository接口实现的 ...
- Spring Data JPA中的动态查询 时间日期
功能:Spring Data JPA中的动态查询 实现日期查询 页面对应的dto类private String modifiedDate; //实体类 @LastModifiedDate protec ...
- spring data jpa使用原生sql查询
spring data jpa使用原生sql查询 @Repository public interface AjDao extends JpaRepository<Aj,String> { ...
- Spring Data JPA 复杂/多条件组合查询
1: 编写DAO类或接口 dao类/接口 需继承 public interface JpaSpecificationExecutor<T> 接口: 如果需要分页,还可继承 public ...
- Spring data jpa 实现简单动态查询的通用Specification方法
本篇前提: SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法 这篇文章中的第二种方法 实现Specification 这块的方法 只适用于一个对象针对某一个固定字 ...
- Spring Data Jpa (四)注解式查询方法
详细讲解声明式的查询方法 1 @Query详解 使用命名查询为实体声明查询是一种有效的方法,对于少量查询很有效.一般只需要关心@Query里面的value和nativeQuery的值.使用声明式JPQ ...
- Spring Data JPA 自定义对象接收查询结果集
Spring Data JPA 简介 Spring Data JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和 ...
- Spring Data JPA 的 Specifications动态查询
主要的结构: 有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询. ...
- Spring Data Jpa的四种查询方式
一.调用接口的方式 1.基本介绍 通过调用接口里的方法查询,需要我们自定义的接口继承Spring Data Jpa规定的接口 public interface UserDao extends JpaR ...
随机推荐
- 【2017-06-29】在登录页面自动返回上次请求页面、Js获取table中的行数与列数
一.在登录页面自动返回上次请求页面 Request.UrlReferrer比如 if (Request.UrlReferrer != null) { //如果能获取来路地址 Response.Redi ...
- awk 内置函数的使用
转自:http://gdcsy.blog.163.com/blog/static/12734360920130241521280/ 一.split 初始化和类型强制 awk的内建函数sp ...
- null 和{}的那点事
直接上代码 console.log(typeof null); //object console.log(typeof {}); //object 可以看到两者的类型都是object ,写在前面的事: ...
- bp算法推导过程
参考:张玉宏<深度学习之美:AI时代的数据处理与最佳实践>265-271页
- 模糊查询的sql语句
Java程序中使用的sql语句一直不明白是什么作用,在网上搜索了一些资料,看到一篇博客,稍微解答了具体每条代码的作用,因为作者加了详细的注解,可以作为参考 <JavaWeb dao层条件查询(模 ...
- 表单文本字段预期描述(placeholder="请输入产品名称"以及prompt:'输入价格')
普通html文本标签设置: <input id="xxx" placeholder="请输入产品名称"/> 带有jQueryEasyUI插件的htm ...
- ACM-ICPC 2018 南京赛区现场赛 E. Eva and Euro coins (思维)
题目链接:https://codeforc.es/gym/101981/attachments 题意:给出两个只包含01的字符串,每次可以选择连续k个相同的数字进行翻转,问能否通过若干次操作把两个字符 ...
- SIGAI深度学习第三集 人工神经网络2
讲授神经网络的理论解释.实现细节包括输入与输出值的设定.网络规模.激活函数.损失函数.初始化.正则化.学习率的设定.实际应用等 大纲: 实验环节: 理论层面的解释:两个方面,1.数学角度,映射函数h( ...
- [DK] 化学竞赛的大奖
https://www.luogu.org/problemnew/show/T16502 无向图 缩点 树的直径 到直径两个端点的距离的较大值 #include <iostream> ...
- idea 启动 Error running 'XxGatewayApplication': Command line is too long. Shorten command line for XxGatewayApplication or also for Spring Boot default
在idea workspace里 <component name="PropertiesComponent">标签下加入 <property name=" ...