如何使用Criteria Builder创建动态查询/过滤器

时间:2019-01-22 08:54:14

标签: java spring jpa spring-data-jpa criteria-api

我想做一个动态查询,以响应以下rest api,例如:

api/misra?sourceCodeCategory=3rd party&sourceCodeCategory=New Code&guidelineSeverity=required&buildId=72 

为此,我创建了一个MisraSpecification类:

public class MisraSpecification implements Specification<MisraMessages> {

    private MultiValueMap<String, String> selectedParameters;

    public MisraSpecification(MultiValueMap<String, String> selectedParameters) {
        this.selectedParameters = selectedParameters;
    }

    @Override
    public Predicate toPredicate(Root<MisraMessages> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

        List<Predicate> predicates = new ArrayList<>();
        Predicate result;

        Predicate buildIdPredicate;
        if (selectedParameters.get("buildId") != null) {
            for (String buildId : selectedParameters.get("buildId")) {
                predicates.add(cb.equal(root.get("fileName"), buildId));
            }
        }
        buildIdPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
        predicates.clear();


        Predicate fileNamePredicate;
        if (selectedParameters.get("fileName") != null) {
            for (String fileName : selectedParameters.get("fileName")) {
                predicates.add(cb.equal(root.get("fileName"), fileName));
            }
        }
        fileNamePredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
        predicates.clear();

        Predicate messageSeverityPredicate;
        if (selectedParameters.get("messageSeverity") != null) {
            for (String messageSeverity : selectedParameters.get("messageSeverity")) {
                predicates.add(cb.equal(root.get("messageSeverity"), messageSeverity));
            }
        }
        messageSeverityPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
        predicates.clear();

        Predicate guidelineSeverityPredicate;
        if (selectedParameters.get("guidelineSeverity") != null) {
            for (String guidelineSeverity : selectedParameters.get("guidelineSeverity")) {
                predicates.add(cb.equal(root.get("guidelineSeverity"), guidelineSeverity));
            }
        }
        guidelineSeverityPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
        predicates.clear();

        Predicate requirementPredicate;
        if (selectedParameters.get("requirement") != null) {
            for (String requirement : selectedParameters.get("requirement")) {
                predicates.add(cb.equal(root.get("requirement"), requirement));
            }
        }
        requirementPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
        predicates.clear();

        Predicate sourceCodeCategoryPredicate;
        if (selectedParameters.get("sourceCodeCategory") != null) {
            for (String sourceCodeCategory : selectedParameters.get("sourceCodeCategory")) {
                predicates.add(cb.equal(root.get("sourceCodeCategory"), sourceCodeCategory));
            }
        }
        sourceCodeCategoryPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
        predicates.clear();

        Predicate functionalityPredicate;
        if (selectedParameters.get("functionality") != null) {
            for (String functionality : selectedParameters.get("functionality")) {
                predicates.add(cb.equal(root.get("functionality"), functionality));
            }
        }
        functionalityPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
        predicates.clear();

        Predicate subFunctionalityPredicate;
        if (selectedParameters.get("subFunctionality") != null) {
            for (String subFunctionality : selectedParameters.get("subFunctionality")) {
                predicates.add(cb.equal(root.get("subFunctionality"), subFunctionality));
            }
        }
        subFunctionalityPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
        predicates.clear();

        Predicate supplierPredicate;
        if (selectedParameters.get("supplier") != null) {
            for (String supplier : selectedParameters.get("supplier")) {
                predicates.add(cb.equal(root.get("supplier"), supplier));
            }
        }
        supplierPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
        predicates.clear();

        Predicate asilLevelPredicate;
        if (selectedParameters.get("asilLevel") != null) {
            for (String asilLevel : selectedParameters.get("asilLevel")) {
                predicates.add(cb.equal(root.get("asilLevel"), asilLevel));
            }
        }
        asilLevelPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
        predicates.clear();

         result = cb.and(cb.or(fileNamePredicate, messageSeverityPredicate, guidelineSeverityPredicate, requirementPredicate,
                sourceCodeCategoryPredicate, functionalityPredicate, subFunctionalityPredicate, supplierPredicate, asilLevelPredicate));

        return cb.and(result);
    }
} 

这是我的控制器

@GetMapping("/misra")
    public Page<MisraMessages> applyFilter(@PageableDefault(value = 10, page = 0) Pageable pageable,
                                           @RequestParam(value = "buildId", required = true) String buildId,
                                           @RequestParam MultiValueMap<String, String> selectedParameters) {

        //add the build to the selected map values
        List<String> build = new ArrayList<String>();
        build.add(buildId);
        selectedParameters.put("buildId", build);

        //apply filter
        Page<MisraMessages> listWithMisraMessageAfterFilter = misraMessagesService.findAllMisraByFilters(pageable, selectedParameters);

在应用过滤器时,在这种情况下,结果是部分正确的。 SourceCodeCategory是“第三方”或“新代码”,但是GuidelineSeverity不遵守过滤器。我收到的对象具有更多的SourceCodeCategory值...经过测试,在控制器中,我收到的GuidelineSeverity值正确。您有解决我问题的方法吗? :)

0 个答案:

没有答案