JPA的动态查询

前几天 使用 jpa 连接 pg 库来开发一个模块 发现这个玩意 平时挺好用 但是涉及到一些复杂一点的动态查询 咱也不多说直接上 代码 然后一点点 解释

首先 使用jpa 的dao层都需要 去继承一个接口来实现curd
第一步 省略。。 创建一个 model
第二步 dao层

public interface OperatorDao extends JpaRepository<OperatorPO, String>, JpaSpecificationExecutor<OperatorPO> {
// 这里就不多说了 类似 mybatisplus  但是  JpaSpecificationExecutor 这个 方法很重要因为 他里面 包含的
/**
  Optional findOne(@Nullable Specification var1);

    List findAll(@Nullable Specification var1);

    Page findAll(@Nullable Specification var1, Pageable var2);

    List findAll(@Nullable Specification var1,  var2);

    long count(@Nullable Specification var1);
*/
// 这些方法 其中 Specification 这个参数 就是我们要实现动态查询 类 而   Pageable  Sort  这两个不用过多
// 介绍  一看就知道一个是排序 一个 是分页
}
第三步 service 层

```java
//OperatorPO 这个就是 你创建的model 也就是表 映射的类
 public Page<OperatorPO> search(SearchVO searchVO) {

        //动态查询
        Specification<OperatorPO> sf = (Specification<OperatorPO>) (root, query, cb) -> {
            //用于添加所有查询条件 如果 使用过es 查询 的人可以很好理解 这里 分层去封装每个层级是事情
            /* 这里使用 java lambda 表达式来创建 如果 使用不习惯可一个去实现类去写
			  root, 者根就是你表的数据  
              query, 就是查询外层的 条件了 where
              cb  就是你要操作的类型 相等 模糊或者 范围
            */
            List<Predicate> p = new ArrayList<>();
            if (StringUtils.isNotBlank(searchVO."传入的字段1")) {
                Predicate p5 = cb.equal(root.get("表的字段1").as(String.class), searchVO."传入的字段1");
                p.add(p5);
            }

            if (StringUtils.isNotBlank(searchVO."传入的字段2")) {
                Predicate p1 = cb.like(root.get("表的字段2").as(String.class), "%"+searchVO."传入的字段2"+"%");
                p.add(p1);
            }
          
            if (StringUtils.isNotBlank(searchVO."传入的开始时间") && StringUtils.isNotBlank(searchVO."传入的开始结束")) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                try {
                    Date start = simpleDateFormat.parse(searchVO."传入的开始时间");
                    Date end = simpleDateFormat.parse(searchVO."传入的开始结束");
                    Predicate p3 = cb.greaterThanOrEqualTo(root.get("表的时间").as(Date.class), start);
                    Predicate p4 = cb.lessThanOrEqualTo(root.get("表的时间").as(Date.class), end);
                    p.add(p3);
                    p.add(p4);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            Predicate[] pre = new Predicate[p.size()];
            // 决定了 每个 操作之间 关系 是并且还是或
            Predicate and = cb.and(p.toArray(pre));     //查询条件 and
            //Predicate or = cb.or(p.toArray(pre));       //查询条件 or
            query.where(and);       //添加查询条件
          	// 返回 这个对象
            return query.getRestriction();
        };
        // 分页操作
        Integer pageNo = searchVO.getPageNo();
        Integer pageSize = searchVO.getRow();
       
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(new Sort.Order(Sort.Direction.DESC, "表要排序的字段"));
        // 排序
        Sort by = Sort.by(orders);
        // 分页
        PageRequest pageRequest = PageRequest.of((pageNo - 1), pageSize, by);
        // 这里是将所有的 条件添加到查询 里面  搜索
        Page<OperatorLogPO> all = operatorDao.findAll(sf, pageRequest);
        return all;
    }

第四部 获取

         Page<OperatorPO> oS = 这里就调用第二步的方法
         // 获取 查询到的总是
        long totalElements = oS .getTotalElements();
        // 获取到 数据流
        Stream<OperatorPO> POStream = oS .get();
        // 转化为 集合
        List<OperatorPO> collect = POStream.collect(Collectors.toList());

你可能感兴趣的:(java,java,开发语言,后端)