JPA Criteria Query 的 變態(tài)例子

某一天有這么一個(gè)簡(jiǎn)單的需求纫骑,一個(gè)頁(yè)面有N種查詢方式蝎亚,這N種參數(shù)可能有也可能沒有,

其他A種查詢方式是“AND”惧磺,剩下的是“OR”颖对。

1.png

某一天有這么一個(gè)簡(jiǎn)單的需求,一個(gè)頁(yè)面有N種查詢方式磨隘,這N種參數(shù)可能有也可能沒有缤底,

并且

·只要查詢其中的某幾個(gè)字段(表和表有關(guān)聯(lián))
·要有分頁(yè)
·要查詢分頁(yè)后的統(tǒng)計(jì)數(shù)據(jù)(簡(jiǎn)單顾患,分頁(yè)后查出來(lái)計(jì)算也行)
·要查詢出分頁(yè)之前所有數(shù)據(jù)的統(tǒng)計(jì)數(shù)據(jù) (這……)

2.png

在有某天有這么一個(gè)簡(jiǎn)單的需求,一個(gè)頁(yè)面有N種查詢方式个唧,這N種參數(shù)可能有也可能沒有江解,

并且

·只要查詢其中的某幾個(gè)字段(表和表有關(guān)聯(lián))
·要有分頁(yè)
·要查詢分頁(yè)后的統(tǒng)計(jì)數(shù)據(jù)(簡(jiǎn)單,分頁(yè)后查出來(lái)計(jì)算也行)
·要查詢出分頁(yè)之前所有數(shù)據(jù)的統(tǒng)計(jì)數(shù)據(jù) (這……)
·需要查詢的幾個(gè)字段和條件有些在一個(gè)不關(guān)聯(lián)的第三方表里面……這個(gè)表的那個(gè)字段有時(shí)候是填這個(gè)表的id徙歼,有時(shí)候是其他表的 或者隨機(jī)字符串?dāng)?shù)據(jù)犁河。
不能直接做關(guān)聯(lián)。

1的例子:

 Page<User>
        userPage = userRepository.findAll(new Specification() {


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

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

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

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

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

                    if (cardGrade == null) {
                        throw new AppException("查無(wú)此卡級(jí)別:" + cardGradeId);
                    }
                    List<Card> cardList = cardRepository.findByStoreIdAndCardGradeAndIsDeleted(storeId, cardGrade, BaseDeleteEnums.BASE_DELETE_NO.getCode());
                    if (cardList != null && cardList.size() > 0) {
                        CriteriaBuilder.In<Card> 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<Card> cardPath = root.get("card");

                    List<Card> cardList = cardRepository.findByStoreIdAndCardStatusAndIsDeleted(storeId, cardStatus, BaseDeleteEnums.BASE_DELETE_NO.getCode());
                    if (cardList != null && cardList.size() > 0) {
                        CriteriaBuilder.In<Card> 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<Integer> provinceIdPath = root.get("provinceId");
                    predicates.add(cb.equal(provinceIdPath.as(Integer.class), provinceId));
                }
                if (cityId != null) {
                    Path<Integer> provinceIdPath = root.get("cityId");
                    predicates.add(cb.equal(provinceIdPath.as(Integer.class), cityId));
                }

                if (balance != null && flag != null && !flag.isEmpty()) {
                    Path<BigDecimal> 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錯(cuò)誤魄梯,應(yīng)為 大于桨螺、等于或小于,而非:" + flag);
                    }

                }

                if (keyword != null && !keyword.isEmpty()) {
                    Path<String> realNamePath = root.get("realName");
                    Path<String> mobilePath = root.get("mobile");
                    Path<String> identityPath = root.get("identity");
                    Path<String> 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<Card> cardPath = root.get("card");
                    List<Card> cardList = cardRepository.findByStoreIdAndSnAndIsDeleted(storeId, keyword, BaseDeleteEnums.BASE_DELETE_NO.getCode());
                    if (cardList != null && cardList.size() > 0) {
                        CriteriaBuilder.In<Card> 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<Card> cardPath = root.get("card");

                    List<Card> cardList = cardRepository.findByStoreIdAndSnAndIsDeleted(storeId, cardsn, BaseDeleteEnums.BASE_DELETE_NO.getCode());
                    if (cardList != null && cardList.size() > 0) {
                        CriteriaBuilder.In<Card> 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<String, Object> resultMap = new HashMap<>();
        Integer storeId = params.containsKey("storeId") ? Integer.parseInt(params.get("storeId").toString()) : 0;
        //增減原因 資金變動(dòng)類型:1-充值酿秸、2-發(fā)放補(bǔ)貼灭翔、3-現(xiàn)金取款、4-補(bǔ)貼取款……
        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<Tuple> criteriaQuery = cb.createTupleQuery();//列表查詢
        CriteriaQuery<Tuple> criteriaQueryCount = cb.createTupleQuery();//統(tǒng)計(jì)查詢
        Root<LogCardCapital> root = criteriaQuery.from(LogCardCapital.class);
        Root<LogCardCapital> 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<Predicate> predicates = new ArrayList<>();

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

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

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

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

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

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

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

        }
        if (realName != null && !realName.isEmpty()) {
            Path<User> userPath = root.get("user");
            Path<String> realNamePath = userPath.get("realName");
            predicates.add(cb.equal(realNamePath.as(String.class), realName));
        }
        if (identity != null && !identity.isEmpty()) {
            Path<User> userPath = root.get("user");
            Path<String> 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<Tuple> list = query.getResultList();


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

            for (Tuple tu : list
                    ) {
                Map<String, Object> 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<Tuple> 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辣苏、詳細(xì)見:http://www.reibang.com/p/6156bf21374c

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肝箱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子稀蟋,更是在濱河造成了極大的恐慌煌张,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件退客,死亡現(xiàn)場(chǎng)離奇詭異骏融,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)萌狂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門绎谦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人粥脚,你說(shuō)我怎么就攤上這事“觯” “怎么了刷允?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)碧囊。 經(jīng)常有香客問(wèn)我树灶,道長(zhǎng),這世上最難降的妖魔是什么糯而? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任天通,我火速辦了婚禮,結(jié)果婚禮上熄驼,老公的妹妹穿的比我還像新娘像寒。我一直安慰自己烘豹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布诺祸。 她就那樣靜靜地躺著携悯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪筷笨。 梳的紋絲不亂的頭發(fā)上憔鬼,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音胃夏,去河邊找鬼轴或。 笑死,一個(gè)胖子當(dāng)著我的面吹牛仰禀,可吹牛的內(nèi)容都是我干的照雁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼悼瘾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼囊榜!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起亥宿,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤卸勺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后烫扼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體曙求,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年映企,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了悟狱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡堰氓,死狀恐怖挤渐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情双絮,我是刑警寧澤浴麻,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站囤攀,受9級(jí)特大地震影響软免,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜焚挠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一膏萧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦榛泛、人聲如沸蝌蹂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)叉信。三九已至,卻和暖如春艘希,著一層夾襖步出監(jiān)牢的瞬間硼身,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工覆享, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留佳遂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓撒顿,卻偏偏與公主長(zhǎng)得像丑罪,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子凤壁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,931評(píng)論 2 89
  • 曾經(jīng)年少輕狂覺得自己有資本吩屹,現(xiàn)在熱臉貼冷屁股覺得自己沒資本。在我生里最殘酷最痛苦的時(shí)候有人跟我說(shuō)人不為己天誅地滅拧抖。...
    濮維浩閱讀 373評(píng)論 0 0
  • 這里我先引進(jìn)一個(gè)心理學(xué)上的名字煤搜,叫做“知識(shí)的詛咒”,說(shuō)的是說(shuō)話者以為對(duì)方了解說(shuō)話者在說(shuō)什么唧席,而只顧自己盡情...
    凡思閱讀 364評(píng)論 12 10
  • 1. 關(guān)于高樓擦盾,不知道怎么概括,大江大河見過(guò)淌哟,清風(fēng)落日見過(guò)迹卢。對(duì)他,枝榆只能說(shuō)徒仓,躲不開腐碱。 十八歲那年,枝榆總覺自己...
    chuyuan0301閱讀 266評(píng)論 0 0