使用spring-data-jpa规范过滤数据

时间:2019-07-25 06:53:34

标签: spring-boot spring-mvc spring-data-jpa spring-data criteria-api

如何使用Spring Data JPA规范过滤数据。

我遵循了: https://www.baeldung.com/rest-api-search-language-spring-data-specifications文章。但是在 Specification.where(结果)中获得UserSpecificationBuilder.java中的错误。

当我点击URL时,我需要过滤掉我的数据。 http://localhost:8080/users?search=cost> 2000

我已将代码上传到gitHub中,分支为 Feature_Filters https://github.com/avinashm294/Test.git

我该如何解决此问题。

Car.java

@Entity
   public class Car {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String username;
    private String cost;

  /*Getter and Setters for id,userName,cost*/
  /*parameterized constructors and toString for the fields*/
   }

UserSpecification.java

public class UserSpecification implements Specification<Car> {

    private SearchCriteria criteria;

    public UserSpecification(final SearchCriteria criteria) {
        super();
        this.criteria = criteria;
    }

    @Override
    public Predicate toPredicate(Root<Car> root, CriteriaQuery<?> query, CriteriaBuilder builder) {

         if (criteria.getOperation().equalsIgnoreCase(">")) {
                return builder.greaterThanOrEqualTo(
                  root.<String> get(criteria.getKey()), criteria.getValue().toString());
            } 
            else if (criteria.getOperation().equalsIgnoreCase("<")) {
                return builder.lessThanOrEqualTo(
                  root.<String> get(criteria.getKey()), criteria.getValue().toString());
            } 
            else if (criteria.getOperation().equalsIgnoreCase(":")) {
                if (root.get(criteria.getKey()).getJavaType() == String.class) {
                    return builder.like(
                      root.<String>get(criteria.getKey()), "%" + criteria.getValue() + "%");
                } else {
                    return builder.equal(root.get(criteria.getKey()), criteria.getValue());
                }
            }
            return null;
    }
}

SerachCriteria.java

public class SearchCriteria {
    private String key;
    private String operation;
    private Object value;
}

CarRepository.java

public interface CarRepository  extends JpaRepository<Car, Long>, JpaSpecificationExecutor<Car>{   
    public List<Car> findByCost(String cost);           
}

SpecificationBuilder.java

public class UserSpecificationsBuilder {

    private final List<SearchCriteria> params;

    public UserSpecificationsBuilder() {
        params = new ArrayList<SearchCriteria>();
    }

    public UserSpecificationsBuilder with(String key, String operation, Object value) {
        params.add(new SearchCriteria(key, operation, value));
        return this;
    }

    public Specification<Car> build() {
        if (params.size() == 0) {
            return null;
        }

        List<Specification> specs = params.stream()
          .map(UserSpecification::new)
          .collect(Collectors.toList());

        Specification result = specs.get(0);

        for (int i = 1; i < params.size(); i++) {
            result = params.get(i)
              .isOrPredicate()
                ? Specification.where(result) //--getting error here
                  .or(specs.get(i))
                : Specification.where(result)
                  .and(specs.get(i));
        }       
        return result;
    }
}

Controller.java

@RestController
@RequestMapping("/car-api")
public class CarController {
@RequestMapping(method = RequestMethod.GET, value = "/Cars")
        @ResponseBody
        public List<Car> search(@RequestParam(value = "search") String search) {
            UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
            Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
            Matcher matcher = pattern.matcher(search + ",");
            while (matcher.find()) {
                builder.with(matcher.group(1), matcher.group(2), matcher.group(3));
            }

            Specification<Car> spec = builder.build();
            return carRepository.findAll(spec);
        }
}

0 个答案:

没有答案