【问题标题】:How to filter List of params with Criteria Builder?如何使用 Criteria Builder 过滤参数列表?
【发布时间】:2020-10-12 19:08:44
【问题描述】:

我的 Spring Boot 应用程序中有过滤器功能,除了需要过滤项目列表时,一切都运行良好。这些项目在我的应用程序中称为“标签”。 当我像这样在 URL 中插入一个标签时

http://localhost:8080/mybrocki/ads/filter?tag=Antique

一切都还好。但是当我插入更多标签时:

http://localhost:8080/mybrocki/ads/filter?tag=Antique&tag=Malfunction

我总是得到空数组(它不应该是)。这是我的控制器

@GetMapping("/ads/filter")
    public ResponseEntity<List<AdsDTO>> getAdsByParam(@RequestParam(required = false) String region,
                                                        @RequestParam(required = false) AdsSubGroup adssubgroup,
                                                        @RequestParam(required = false) Long userId,
                                                        @RequestParam(required = false) String status,
                                                        @RequestParam(required = false) String businessType,
                                                        @RequestParam(required = false) String adsType,
                                                        @RequestParam(required = false) Long adsGroupId,
                                                        @RequestParam(required = false) Integer fromPrice,
                                                        @RequestParam(required = false) Integer toPrice,
                                                        @RequestParam(required = false) Boolean fixedPrice,
                                                        @RequestParam(required = false) Boolean freeDelivery,
                                                        @RequestParam(required = false) Boolean productWarranty,
                                                        @RequestParam(required = false) Boolean urgentSales,
                                                        @RequestParam(required = false)Boolean hasImage,
                                                        @RequestParam(required = false) Integer pageNumber,
                                                        @RequestParam(required = false) Integer pageSize,
                                                        @RequestParam(required = false, value = "tag") List<String> tags) throws ForbiddenException {
        return new ResponseEntity<List<AdsDTO>>(adsServiceImplement.findAll(adssubgroup, userId, status, adsType, businessType, adsGroupId, region, fromPrice, toPrice, fixedPrice, freeDelivery, productWarranty, urgentSales, hasImage, pageNumber, pageSize, tags), HttpStatus.OK);
    }

这是我的过滤方法:

 @Override
        public List<AdsDTO> findAll(AdsSubGroup adssubgroup, Long userId, String status, String adsType, 
                                    String businessType, Long adsGroupId, String region, Integer fromPrice, 
                                    Integer toPrice, Boolean fixedPrice, Boolean freeDelivery, Boolean productWarranty, 
                                    Boolean urgentSales, Boolean hasImage, Integer pageNumber, Integer pageSize, List<String> tags) {

         CriteriaBuilder builder = em.getCriteriaBuilder();
         CriteriaQuery<Ads> query = builder.createQuery(Ads.class);
         Root<Ads> ads = query.from(Ads.class);
         query.orderBy(builder.desc(ads.get("adsDate")));
         List<Predicate> predicates = new ArrayList<>();
         Join<Ads, JwtUser> adsUsersJoin = ads.join("users");
         Join<Ads, AdsSubGroup> adsAdsSubGroupJoin = ads.join("adssubgroup");
         Join<Ads, Tag> tagsJoin = ads.join("adsTags");

         if (!Objects.isNull(adsGroupId)) {
             predicates.add(builder.equal(adsAdsSubGroupJoin.get("adsGroupId"), adsGroupId));
         }
         if (!Objects.isNull(adssubgroup)) {
             predicates.add(builder.equal(ads.get("adssubgroup"),adssubgroup));
         }

         if (!StringUtils.isEmpty(region)) {
             predicates.add(builder.like(adsUsersJoin.get("region"), region));
         }

         if (!StringUtils.isEmpty(businessType)) {
             predicates.add(builder.equal(adsUsersJoin.get("businessType"), businessType ));
         }
         
         if (!StringUtils.isEmpty(status)) {
             
             predicates.add(builder.equal(ads.get("status"), status));
         }
         
         if (!Objects.isNull(userId)) {
             
             predicates.add(builder.equal(ads.get("userId"), userId));
         }

         if (!StringUtils.isEmpty(adsType)) {
             predicates.add(builder.equal(ads.get("adsType"), adsType));
         }

         if (!Objects.isNull(fromPrice) && !Objects.isNull(toPrice) && fromPrice < toPrice) {
                predicates.add(builder.between(ads.get("price"), fromPrice, toPrice));
            }

         if (!Objects.isNull(fixedPrice)) {
             if (fixedPrice) {
             predicates.add(builder.equal(ads.get("fixedPrice"), true));
             } else {
             predicates.add(builder.equal(ads.get("fixedPrice"), false));
             }
         }

         if (!Objects.isNull(freeDelivery)) {
             if (freeDelivery) {
             predicates.add(builder.equal(ads.get("freeDelivery"), true));
             } else {
             predicates.add(builder.equal(ads.get("freeDelivery"), false));
             }
         }

         if (!Objects.isNull(productWarranty)) {
             if (productWarranty) {
             predicates.add(builder.equal(ads.get("productWarranty"), true));
             } else {
             predicates.add(builder.equal(ads.get("productWarranty"), false));
             }
         }

         if (!Objects.isNull(urgentSales)) {
             if (urgentSales) {
             predicates.add(builder.equal(ads.get("urgentSales"), true));
             } else {
             predicates.add(builder.equal(ads.get("urgentSales"), false));
             }
         }

         if (!Objects.isNull(hasImage)) {
             if (hasImage) {
                 predicates.add(builder.isNotNull(ads.get("image")));
             } else {
                 predicates.add(builder.isNull(ads.get("image")));
             }
         }
         
            
              if (tags != null && tags.size() > 0) { 
                  for (String tag : tags) {
                  predicates.add(builder.equal(tagsJoin.get("name"), tag));
                  }
              }
              query.select(ads);
         query.where(predicates.toArray(new Predicate[0]));
         if(!(pageNumber==null && pageSize==null)) {
             TypedQuery<Ads> typedQuery = em.createQuery(query);
             typedQuery.setFirstResult((pageNumber-1)*pageSize);
             typedQuery.setMaxResults(pageSize);
             List<Ads> adsList = typedQuery.getResultList();
             return AdsConverter.convertToAdsDTO(adsList);
         }else {
             List<Ads> adsList = em.createQuery(query).getResultList();
             return AdsConverter.convertToAdsDTO(adsList);
         }
 
     }

谁能告诉我哪里错了?

【问题讨论】:

  • 附带说明 - 你知道你可以使用一个对象作为控制器参数并且请求参数将映射到属性?
  • 是的,我知道,但正如我从那方面所说的,一切都很好,查询中的某些内容不正常......
  • 试试tag[]=Antique&amp;tag[]=Malfunction

标签: java spring spring-boot hibernate hibernate-criteria


【解决方案1】:

如果您将提供如下所示的参数,它应该可以工作:

http://localhost:8080/mybrocki/ads/filter?tag=Antique,Malfunction

【讨论】:

  • 所以问题是 findAll() 收到空标签或 getAdsByParam() 收到空标签?
  • 我调试了它,从那方面来看,一切都很好,我有 URl 中的标签列表,也许我的 foreach 迭代该列表中的每个标签是错误的
  • 好的,我认为您在将值从 URL 映射到控制器中的列表时遇到问题。
  • 不,不,我认为我的过滤有问题..:)
猜你喜欢
  • 2021-06-18
  • 2014-09-01
  • 2021-03-27
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多