spring data jpa多条件查询

本文介绍如何在Spring Data JPA中使用Specification进行多条件查询,特别是利用Predicate进行断言查询,以替代原生SQL或@Query注解。内容包含了一个涉及嵌套子查询的代码实例,以及枚举类型转换和查询时间范围的方法。
摘要由CSDN通过智能技术生成

spring data jpa多条件查询

主要是工作中用到的关于jpa的条件查询,使用了Specification的Predicate(断言查询)条件查询代替原生sql或@Query注解:

  • 记录一下工作时的代码片段,这里用到了一个嵌套的子查询
/**
 * 展示列表和条件查询(多条件查询)
 * @param status
 * @param createTime
 * @param orderNum
 * @param modelName
 * @param pageable
 * @return
 */
@Override
public Page<OrderVO> getAllOrderTaking(String status, String createTime, String orderNum, String modelName, Pageable pageable) {
    Specification<Order> specification = new Specification<Order>() {
      @Override
      public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

        List<Predicate> predicates = new ArrayList<>();
        Predicate p1 = criteriaBuilder.equal(root.get("status"),Order.Status.valueOf("待审核"));
        Predicate p2 = criteriaBuilder.equal(root.get("status"),Order.Status.valueOf("处理中"));
        Predicate p3 = criteriaBuilder.equal(root.get("status"),Order.Status.valueOf("重做"));
        Predicate predicate1 = null;
        Predicate predicate2 = null;
        if(StringUtils.isNotEmpty(modelName) || StringUtils.isNotEmpty(status) || StringUtils.isNotEmpty(createTime) || StringUtils.isNotEmpty(orderNum)){
          if(null != status){
            predicates.add(criteriaBuilder.equal(root.get("status"),Order.Status.valueOf(status)));
          }
          if(null != modelName){
            Subquery<String> categoryName = criteriaQuery.subquery(String.class);
            Root<Category> categoryRoot = categoryName.from(Category.class);

            categoryName.select(categoryRoot.get("categoryNum")).where(criteriaBuilder.like(categoryRoot.get("name"),"%"+modelName+"%"));

            Subquery<String> categoryNum = criteriaQuery.subquery(String.class);

            Root<Goods> goodsRoot = categoryNum.from(Goods.class);

            categoryNum.select(goodsRoot.get("id")).where(goodsRoot.get("categoryNum").in(categoryName));

            predicate1 = criteriaBuilder.in(root.get("goodsId")).value(categoryNum);

          }
          if(null != createTime && !"".equals(createTime)){
            try {
              if(StringUtils.isEmpty(status)){
                predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"), new SimpleDateFormat(DATE_FORMAT).parse(createTime + TIME_MIN)));
                predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime"), new SimpleDateFormat(DATE_FORMAT).parse(createTime + TIME_MAX)));
                predicates.add(criteriaBuilder.or(p1,p2,p3));
              }else{
                predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"), new SimpleDateFormat(DATE_FORMAT).parse(createTime + TIME_MIN)));
                predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime"), new SimpleDateFormat(DATE_FORMAT).parse(createTime + TIME_MAX)));
              }

            } catch (ParseException e) {
              throw new RuntimeException("日期格式化失败!");
            }
          }
          if(null != orderNum && !"".equals(orderNum)){
            predicate2 = criteriaBuilder.like(root.get("orderNum"), "%"+orderNum+"%");
          }
          if(StringUtils.isNotEmpty(orderNum) & StringUtils.isNotEmpty(modelName)){
            if(StringUtils.isEmpty(status)){
              predicates.add(criteriaBuilder.or(predicate1,predicate2));
              predicates.add(criteriaBuilder.or(p1,p2,p3));
            }else{
              predicates.add(criteriaBuilder.or(predicate1,predicate2));
            }
          }
        }else{

          predicates.add(criteriaBuilder.or(p1,p2,p3));
        }
        return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
      }
    };
    Page<Order> page = orderRepository.findAll(specification,pageable);
    //组装vo实体
    List<OrderVO> orderVOS = new ArrayList<>();
    page.getContent().stream().forEach(order -> {
      OrderVO orderVO = new OrderVO();
      Goods goods = goodsRepository.findOne(order.getGoodsId());
      orderVO.setOrder(order);
      Category category = categoryRepository.findByCategoryNum(goods.getCategoryNum());
      orderVO.setBrand(category.getParent().getName());
      orderVO.setModel(category.getName());
      String usersec = Crypt.crypt(order.getKkmoveId(),secretKey);
      orderVO.setUsersec(usersec);
      orderVO.setKkmoveShop(kkmoveShop);
      orderVO.setMaterial(goods.getMaterial().getName());
      orderVO.setTechnology(goods.getTechnology().getName());
      orderVOS.add(orderVO);
    });
    Page<OrderVO> voPage = new PageImpl<>(orderVOS,pageable,page.getTotalElements());
    return voPage;
  }
  • 代码部分解析
//categoryName是我们需要查询的列(字段)
Subquery<String> categoryName = criteriaQuery.subquery(String.class);
//Root(实体对应的数据库表)
Root<Category> categoryRoot = categoryName.from(Category.class);
//通过单表的查询需要的列并添加where条件        categoryName.select(categoryRoot.get("categoryNum")).where(criteriaBuilder.like(categoryRoot.get("name"),"%"+modelName+"%"));
//同样categoryNum是我们需要查询的列(字段),但不在同在一张表中
Subquery<String> categoryNum = criteriaQuery.subquery(String.class);
Root<Goods> goodsRoot = categoryNum.from(Goods.class);            categoryNum.select(goodsRoot.get("id")).where(goodsRoot.get("categoryNum").in(categoryName));
predicate1 = criteriaBuilder.in(root.get("goodsId")).value(categoryNum);
  • 枚举类型的转换
Predicate p1 = criteriaBuilder.equal(root.get("status"),Order.Status.valueOf("待审核"));
  • 查询时间段
private final static String TIME_MIN = " 00:00:00 000";

private final static String TIME_MAX = " 23:59:59 999";

private final static String DATE_FORMAT = "yyyy-MM-dd hh:mm:ss SSS";
//查询是否在两个时间段之间
predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"), new SimpleDateFormat(DATE_FORMAT).parse(createTime + TIME_MIN)));
                predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime"), new SimpleDateFormat(DATE_FORMAT).parse(createTime + TIME_MAX)));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值