springdatajpa实现多条件查询(分页和不分页)
  ⽬前的spring data jpa已经帮我们⼲了CRUD的⼤部分活了,但如果有些活它⼲不了(CrudRepository接⼝中没定义),那么只能由我们⾃⼰⼲了。这⾥要说的就是在它的框架⾥,如何实现⾃⼰定制的多条件查询。下⾯以我的例⼦说明⼀下:业务场景是我现在有张订单表,我想要⽀持根据订单状态、订单当前处理⼈和订单⽇期的起始和结束时间这⼏个条件⼀起查询。
  先看分页的,⽬前spring data jpa给我们做分页的Repository是PagingAndSortingRepository,但它满⾜不了⾃定义查询条件,只能另选JpaRepository。那么不分页的Repository呢?其实还是它。接下来看怎么实现:
  Repository:
del.Flow;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.pository.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.("currentOperator"), userName));
}
if (status != null) {
predicateList.add(criteriaBuilder.("status"), status));
}
if (createTimeStart != null && createTimeEnd != null) {
predicateList.add(criteriaBuilder.("createTime"), createTimeStart, createTimeEnd));
}
return criteriaBuilder.Array(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) {
<("--queryFlowByCondition-- error : ", e);
}
return result;
}
  上⾯我们可以看到,套路很简单,就是两板斧:先通过Specification对象定义好⾃定义的多查询条件,我这⾥的条件是当传了当前⽤户时,那么将它加⼊到查询条件中,不传该参数⾃然就不加,同理,传了订单状态的话那是通过相等来判断,最后,如果传了起始和结束时间,通过between来查在起始和结束之间的数据;第⼆板斧调⽤我们在Repository中定义好的findAll⽅法,如果分页就⽤带Pageable分页对象参数的⽅法,不分页不带该参数即可。
  如果你的⾃定义查询条件⾥需要模糊查询,⽐如我有个订单ID要⽀持模糊查询,也很简单:
if (orderId!= null) {
predicateList.add(criteriaBuilder.("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.("currentOperator"), userName));
}
if (status != null) {
predicateList.add(criteriaBuilder.("status"), status));
}
if (createTimeStart != null && createTimeEnd != null) {
predicateList.add(criteriaBuilder.("createTime"), createTimeStart, createTimeEnd));
}
return criteriaBuilder.Array(new Predicate[predicateList.size()]));springframework和springboot
}
};
try {
total = unt(countCondition);
} catch (Exception e) {
<("--getCountsByCondition-- error: ", e);
}
return total;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。