JPA Criteria Query 的 变态例子

某一天有这么一个简单的需求,一个页面有N种查询方式,这N种参数可能有也可能没有,

其他A种查询方式是“AND”,剩下的是“OR”。

JPA Criteria Query 的 变态例子_第1张图片
1.png

某一天有这么一个简单的需求,一个页面有N种查询方式,这N种参数可能有也可能没有,

并且

·只要查询其中的某几个字段(表和表有关联)
·要有分页
·要查询分页后的统计数据(简单,分页后查出来计算也行)
·要查询出分页之前所有数据的统计数据 (这……)

JPA Criteria Query 的 变态例子_第2张图片
2.png

在有某天有这么一个简单的需求,一个页面有N种查询方式,这N种参数可能有也可能没有,

并且

·只要查询其中的某几个字段(表和表有关联)
·要有分页
·要查询分页后的统计数据(简单,分页后查出来计算也行)
·要查询出分页之前所有数据的统计数据 (这……)
·需要查询的几个字段和条件有些在一个不关联的第三方表里面……这个表的那个字段有时候是填这个表的id,有时候是其他表的 或者随机字符串数据。
不能直接做关联。

1的例子:

 Page
        userPage = userRepository.findAll(new Specification() {


            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder cb) {
                List predicates = new ArrayList<>();
                List predicatesOr = new ArrayList<>();

                if (departId != null && departId > 0) {
                    Path departIdPath = root.get("depart");
                    Depart depart = departRepository.findByStoreIdAndIdAndIsDeleted(storeId, departId, BaseDeleteEnums.BASE_DELETE_NO.getCode());
                    if (depart == null) {
                        throw new AppException("查无此部门:" + departId);
                    }

                    predicates.add(cb.equal(departIdPath.as(Depart.class), depart));
                }
                if (postId != null && postId > 0) {
                    Path postIdPath = root.get("post");
                    Post post = postRepository.findByStoreIdAndIdAndIsDeleted(storeId, postId, BaseDeleteEnums.BASE_DELETE_NO.getCode());
                    if (post == null) {
                        throw new AppException("查无此职位:" + postId);
                    }

                    predicates.add(cb.equal(postIdPath.as(Post.class), post));
                }
                if (cardGradeId != null && cardGradeId > 0) {

                    DebugPrint.i("cardGradeId", cardGradeId + "");
                    Path cardPath = root.get("card");
                    CardGrade cardGrade = cardGradeRepository.findByStoreIdAndIdAndIsDeleted(storeId, cardGradeId, BaseDeleteEnums.BASE_DELETE_NO.getCode());

                    if (cardGrade == null) {
                        throw new AppException("查无此卡级别:" + cardGradeId);
                    }
                    List cardList = cardRepository.findByStoreIdAndCardGradeAndIsDeleted(storeId, cardGrade, BaseDeleteEnums.BASE_DELETE_NO.getCode());
                    if (cardList != null && cardList.size() > 0) {
                        CriteriaBuilder.In in = cb.in(cardPath);
                        for (int i = 0; i < cardList.size(); i++) {
                            in.value(cardList.get(i));
                        }


                        predicates.add(in);
                    } else {

                        predicates.add(cb.equal(root.get("id").as(Integer.class), -1));
                    }

                }
                if (cardStatus != null) {

                    DebugPrint.i("cardStatus", cardStatus + "");
                    Path cardPath = root.get("card");

                    List cardList = cardRepository.findByStoreIdAndCardStatusAndIsDeleted(storeId, cardStatus, BaseDeleteEnums.BASE_DELETE_NO.getCode());
                    if (cardList != null && cardList.size() > 0) {
                        CriteriaBuilder.In in = cb.in(cardPath);
                        for (int i = 0; i < cardList.size(); i++) {
                            in.value(cardList.get(i));
                        }


                        predicates.add(in);

                    } else {
                        predicates.add(cb.equal(root.get("id").as(Integer.class), -1));
                    }

                }
                if (provinceId != null) {
                    DebugPrint.i("provinceId", provinceId + "");
                    Path provinceIdPath = root.get("provinceId");
                    predicates.add(cb.equal(provinceIdPath.as(Integer.class), provinceId));
                }
                if (cityId != null) {
                    Path provinceIdPath = root.get("cityId");
                    predicates.add(cb.equal(provinceIdPath.as(Integer.class), cityId));
                }

                if (balance != null && flag != null && !flag.isEmpty()) {
                    Path provinceIdPath = root.get("balance");

                    if (flag.equals("大于")) {
                        predicates.add(cb.ge(provinceIdPath.as(BigDecimal.class), balance));

                    } else if (flag.equals("等于")) {
                        predicates.add(cb.equal(provinceIdPath.as(BigDecimal.class), balance));

                    } else if (flag.equals("小于")) {
                        predicates.add(cb.le(provinceIdPath.as(BigDecimal.class), balance));

                    } else {
                        throw new AppException("flag错误,应为 大于、等于或小于,而非:" + flag);
                    }

                }

                if (keyword != null && !keyword.isEmpty()) {
                    Path realNamePath = root.get("realName");
                    Path mobilePath = root.get("mobile");
                    Path identityPath = root.get("identity");
                    Path idcardPath = root.get("idcard");
                    predicatesOr.add(cb.like(realNamePath.as(String.class), "%" + keyword + "%"));
                    predicatesOr.add(cb.like(mobilePath.as(String.class), "%" + keyword + "%"));
                    predicatesOr.add(cb.like(identityPath.as(String.class), "%" + keyword + "%"));
                    predicatesOr.add(cb.like(idcardPath.as(String.class), "%" + keyword + "%"));
                    Path cardPath = root.get("card");
                    List cardList = cardRepository.findByStoreIdAndSnAndIsDeleted(storeId, keyword, BaseDeleteEnums.BASE_DELETE_NO.getCode());
                    if (cardList != null && cardList.size() > 0) {
                        CriteriaBuilder.In in = cb.in(cardPath);
                        for (int i = 0; i < cardList.size(); i++) {
                            in.value(cardList.get(i));
                        }
                        predicatesOr.add(in);
                    }


                }
                if (cardsn != null && !cardsn.isEmpty()) {
                    DebugPrint.i("sn", cardsn + "");
                    Path cardPath = root.get("card");

                    List cardList = cardRepository.findByStoreIdAndSnAndIsDeleted(storeId, cardsn, BaseDeleteEnums.BASE_DELETE_NO.getCode());
                    if (cardList != null && cardList.size() > 0) {
                        CriteriaBuilder.In in = cb.in(cardPath);
                        for (int i = 0; i < cardList.size(); i++) {
                            in.value(cardList.get(i));
                        }


                        predicates.add(in);

                    } else {
                        predicates.add(cb.equal(root.get("id").as(Integer.class), -1));
                    }


                }

                Predicate[] pre = new Predicate[predicates.size()];
                criteriaQuery.where(predicates.toArray(pre)).where();

                Predicate predicatesWhere = cb.and(predicates.toArray(pre));

                if (predicatesOr.size() > 0) {
                    Predicate[] preOr = new Predicate[predicatesOr.size()];
                    criteriaQuery.where(predicatesOr.toArray(preOr)).where();
                    Predicate predicatesWhereOr = cb.or(predicatesOr.toArray(preOr));
                    return criteriaQuery.where(predicatesWhere, predicatesWhereOr).getRestriction();
                }


                return cb.and(predicates.toArray(pre));
            }
        }, pageable);

2的例子

   @PersistenceContext
    private EntityManager em;



Map resultMap = new HashMap<>();
        Integer storeId = params.containsKey("storeId") ? Integer.parseInt(params.get("storeId").toString()) : 0;
        //增减原因 资金变动类型:1-充值、2-发放补贴、3-现金取款、4-补贴取款……
        Integer type = params.containsKey("type") ? Integer.parseInt(params.get("type").toString()) : 0;
        Integer managerId = params.containsKey("managerId") ? Integer.parseInt(params.get("managerId").toString()) : 0;
        Integer departId = params.containsKey("departId") ? Integer.parseInt(params.get("departId").toString()) : 0;
        Date beginTime = params.containsKey("beginTime") ? DateUtils.String2Date(params.get("beginTime").toString(), "yyyy-MM-dd HH:mm:ss") : null;
        Date endTime = params.containsKey("endTime") ? DateUtils.String2Date(params.get("endTime").toString(), "yyyy-MM-dd HH:mm:ss") : null;
        String realName = params.containsKey("realName") ? params.get("realName").toString() : null;
        String identity = params.containsKey("identity") ? params.get("identity").toString() : null;


//定义查询字段与别名
        String alia_id = "id";
        String alia_realName = "realName";
        String alia_identity = "identity";
        String alia_departTitle = "departTitle";
        String alia_changeBalance = "changeBalance";
        String alia_changeSubsidy = "changeSubsidy";
        String alia_changeDonation = "changeDonation";
        String alia_balance = "balance";
        String alia_subsidy = "subsidy";
        String alia_donation = "donation";
        String alia_cardSn = "cardSn";
        String alia_type = "type";
        String alia_referer = "referer";
        String alia_managerName = "managerName";
        String alia_createTime = "createTime";

        String alia_total = "total";
        String alia_sumChangeBalance = "sumChangeBalance";
        String alia_sumChangeSubsidy = "sumChangeSubsidy";
        String alia_sumChangeDonation = "sumChangeDonation";


        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery criteriaQuery = cb.createTupleQuery();//列表查询
        CriteriaQuery criteriaQueryCount = cb.createTupleQuery();//统计查询
        Root root = criteriaQuery.from(LogCardCapital.class);
        Root rootCount = criteriaQueryCount.from(LogCardCapital.class);


        criteriaQuery.multiselect(

                root.get("id").alias(alia_id),
                root.get("user").get("realName").alias(alia_realName),
                root.get("user").get("identity").alias(alia_identity),
                root.get("user").get("depart").get("title").alias(alia_departTitle),
                root.get("user").get("card").get("sn").alias(alia_cardSn),
                root.get("referer").alias(alia_referer),
                root.get("type").alias(alia_type),
                root.get("managerName").alias(alia_managerName),
                root.get("createTime").alias(alia_createTime),
                root.get("changeBalance").alias(alia_changeBalance),
                root.get("changeSubsidy").alias(alia_changeSubsidy),
                root.get("changeDonation").alias(alia_changeDonation),
                root.get("balance").alias(alia_balance),
                root.get("subsidy").alias(alia_subsidy),
                root.get("donation").alias(alia_donation)

        );
        criteriaQueryCount.multiselect(
                cb.count(rootCount.get("id")).alias(alia_total),
                cb.sum(rootCount.get("changeBalance")).alias(alia_sumChangeBalance),
                cb.sum(rootCount.get("changeDonation")).alias(alia_sumChangeSubsidy),
                cb.sum(rootCount.get("changeDonation")).alias(alia_sumChangeDonation)

        );


        List predicates = new ArrayList<>();

        if (storeId != null && storeId > 0) {

            Path storeIdPath = root.get("storeId");
            predicates.add(cb.equal(storeIdPath.as(Integer.class), storeId));

        }
        //增减原因
        if (type != null && type > 0) {
            Path typePath = root.get("type");
            predicates.add(cb.equal(typePath.as(Integer.class), type));

        }
        if (managerId != null && managerId > 0) {
            Path managerIdPath = root.get("managerId");
            predicates.add(cb.equal(managerIdPath.as(Integer.class), managerId));

        }
        if (beginTime != null) {
            Path createTimePath = root.get("createTime");
            predicates.add(cb.greaterThanOrEqualTo(createTimePath.as(Date.class), beginTime));

        }
        if (endTime != null) {
            Path createTimePath = root.get("createTime");
            predicates.add(cb.lessThanOrEqualTo(createTimePath.as(Date.class), endTime));

        }
        if (departId != null && departId > 0) {
            Path userPath = root.get("user");
            Path departPath = userPath.get("depart");
            Depart depart = departRepository.findByStoreIdAndIdAndIsDeleted(storeId, departId, BaseDeleteEnums.BASE_DELETE_NO.getCode());
            if (depart == null) {
                throw new AppException("查无此部门:" + departId);
            }
            predicates.add(cb.equal(departPath.as(Depart.class), depart));

        }
        if (realName != null && !realName.isEmpty()) {
            Path userPath = root.get("user");
            Path realNamePath = userPath.get("realName");
            predicates.add(cb.equal(realNamePath.as(String.class), realName));
        }
        if (identity != null && !identity.isEmpty()) {
            Path userPath = root.get("user");
            Path identityPath = userPath.get("identity");
            predicates.add(cb.equal(identityPath.as(String.class), identity));
        }

        criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
        criteriaQueryCount.where(predicates.toArray(new Predicate[predicates.size()]));

        TypedQuery query = em.createQuery(criteriaQuery);
        //int totalRows = query.getResultList().size();
        query.setFirstResult(pageNum * pageSize);
        query.setMaxResults(pageSize);
        List list = query.getResultList();


        List> dataList = new ArrayList<>();
        if (list != null && !list.isEmpty()) {

            for (Tuple tu : list
                    ) {
                Map itemmap = new HashMap<>();
                for (TupleElement element : tu.getElements()) {
                    if (element.getAlias().toString().equalsIgnoreCase(alia_type)) {

                        try {
                            itemmap.put(alia_type + "Title", EnumsUtil.getEnumObject(Integer.parseInt(tu.get(element.getAlias()).toString()),
                                    CardCapitalTypeEnums.class).getMsg());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } else if (element.getAlias().toString().equalsIgnoreCase(alia_referer)) {
                        try {
                            itemmap.put(alia_referer + "Title", EnumsUtil.getEnumObject(Integer.parseInt(tu.get(element.getAlias()).toString()),
                                    RefererEnums.class).getMsg());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    itemmap.put(element.getAlias(), tu.get(element.getAlias()));

                }
                dataList.add(itemmap);
            }


        }
        resultMap.put("list", dataList);
        resultMap.put("page", pageNum);
        resultMap.put("pageSize", pageSize);
        resultMap.put("number", dataList.size());
        TypedQuery queryCount = em.createQuery(criteriaQueryCount);
        List listcount = queryCount.getResultList();
        if (listcount != null && !listcount.isEmpty()) {

            Tuple tu = listcount.get(0);
            for (TupleElement element : tu.getElements()) {
                resultMap.put(element.getAlias(), tu.get(element.getAlias()));

            }
        }

3、详细见:https://www.jianshu.com/p/6156bf21374c

你可能感兴趣的:(JPA Criteria Query 的 变态例子)