Как создать динамический запрос / фильтр с помощью Criteria Builder - PullRequest
0 голосов
/ 22 января 2019

Я хочу сделать динамический запрос, который отвечает на следующие 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. У вас есть решение моей проблемы? :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...