JPA複雑なクエリーのソート

6947 ワード

私たちのプロジェクトで使用しているJPAはデータベースとのインタラクションを実現していますが、今回は注文を一定のルールでソートする必要があります.以前はアイテムがpageableで返却データをカプセル化していたので、pageable自体はソート処理がありましたが、jpaはまだ使っていないので、資料を調べてみると、データのソートも可能であることがわかりましたので、ここに記録します.
PredicateをCriteriaQueryに適用します.並べ替えやグループ化など、CriteriaQueryに他の機能を追加することもできますから.次の図に、ソースコードを示します.
まず、削除されたデータとlocationInfoIdをフィルタリングし、deliveryType、orderPaytimeフィールドに基づいてデータをソートします.最初の3つのdeliveryTypeの受注が前に並び、orderPaytimeで昇順に並び、後の2つの受注が後ろに並び、orderPaytimeで昇順に並びます.
Specification specification =
                (Specification) (root, criteriaQuery, criteriaBuilder) -> {
                    List predicates = new ArrayList<>();

                    //         
                    predicates.add(criteriaBuilder.equal(root.get("dataStatus"), AuditModel.DATA_STATUS_ACTVIE));

                    if (null != locationInfoId) {
                        predicates.add(criteriaBuilder.equal(root.get("locationInfoId"), locationInfoId));
                    }
                    if (!StringUtils.isEmpty(shipStatus)) {
                        CriteriaBuilder.In in = criteriaBuilder.in(root.get("orderLatestStatus"));
                        String[] shipStatusArray = StringUtils.split(shipStatus, ',');
                        Arrays.stream(shipStatusArray).forEach(x -> {
                            in.value(Integer.valueOf(x));
                        });
                        predicates.add(in);
                    }

                    criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
                    criteriaQuery.orderBy(
                            //    deliveryType      
                            criteriaBuilder.asc(
                                    criteriaBuilder.selectCase()
                                            .when(criteriaBuilder.equal(
                                                    root.get("deliveryType"), "Home delivery 2h"), 1)
                                            .when(criteriaBuilder.equal(
                                                    root.get("deliveryType"), "C&C 2h"), 1)
                                            .when(criteriaBuilder.equal(
                                                    root.get("deliveryType"), "tmalldss"), 1)
                                            .when(criteriaBuilder.equal(
                                                    root.get("deliveryType"), "Home delivery"), 3)
                                            .when(criteriaBuilder.equal(
                                                    root.get("deliveryType"), "C&C"), 3)
                                            .otherwise(99)),
                            //    orderPaytime    
                            criteriaBuilder.asc(root.get("orderPaytime"))
                    );
                    return criteriaQuery.getRestriction();
                };
  • もちろん、likeはファジイマッチングを行い、gtは入力パラメータより大きいデータをフィルタし、ltは入力パラメータより小さいデータをフィルタする.
  • Specification spec = new Specification() {  
                        public Predicate toPredicate(Root root,  
                                                                CriteriaQuery> query, CriteriaBuilder cb) {  
                            Predicate p1 = cb.like(root.get("name").as(String.class), "%"+um.getName()+"%");  
                            Predicate p2 = cb.equal(root.get("uuid").as(Integer.class), um.getUuid());  
                            Predicate p3 = cb.gt(root.get("age").as(Integer.class), um.getAge());  
                            // Predicate   CriteriaQuery  ,      CriteriaQuery       ,    、      
                            query.where(cb.and(p3,cb.or(p1,p2)));  
                            //         
                            query.orderBy(cb.desc(root.get("uuid").as(Integer.class)));  
                              
                            return query.getRestriction();  
                        }  
                                        };
  • には、複雑な条件の組合せクエリー
  • もあります.
    Specification specification =
                    (Specification) (root, criteriaQuery, criteriaBuilder) -> {
                        List predicates = new ArrayList<>();
    
                        //         
                        predicates.add(criteriaBuilder.equal(root.get("dataStatus"), AuditModel.DATA_STATUS_ACTVIE));
    
                        if (null != locationInfoId) {
                            predicates.add(criteriaBuilder.equal(root.get("locationInfoId"), locationInfoId));
                        }
                        if (!StringUtils.isEmpty(shipStatus)) {
                            CriteriaBuilder.In in = criteriaBuilder.in(root.get("orderLatestStatus"));
                            String[] shipStatusArray = StringUtils.split(shipStatus, ',');
                            Arrays.stream(shipStatusArray).forEach(x -> {
                                in.value(Integer.valueOf(x));
                            });
                            predicates.add(in);
                        }
    
                        criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
                        criteriaQuery.orderBy(
                                //    deliveryType      
                                criteriaBuilder.asc(
                                        criteriaBuilder.selectCase()
                                                .when(criteriaBuilder.equal(
                                                        root.get("deliveryType"), "Home delivery 2h"), 1)
                                                .when(criteriaBuilder.equal(
                                                        root.get("deliveryType"), "C&C 2h"), 1)
                                                .when(criteriaBuilder.equal(
                                                        root.get("deliveryType"), "tmalldss"), 1)
                                                .when(criteriaBuilder.equal(
                                                        root.get("deliveryType"), "Home delivery"), 3)
                                                .when(criteriaBuilder.equal(
                                                        root.get("deliveryType"), "C&C"), 3)
                                                .otherwise(99)),
                                //    orderPaytime    
                                criteriaBuilder.asc(root.get("orderPaytime"))
                        );
                        return criteriaQuery.getRestriction();
                    };