Могу ли я создать общий @Query, который определяет, какие параметры из URL не равны NULL, и выполнять поиск только по ним с помощью Spring? - PullRequest
0 голосов
/ 17 мая 2019

Могу ли я создать общий @Query, который определяет, какие параметры из URL не являются нулевыми, и выполнять поиск только по ним, вместо создания метода для каждой комбинации параметров с Spring Framework?

Например:У меня есть два параметра в моем URL;Я хочу сделать только один запрос, который определяет ненулевые параметры из моего URL-адреса и передать их в мой запрос, игнорируя пустые значения (вместо создания большого количества if / else и разных запросов для комбинации различных параметров).

Я создал этот код, который возвращает список стран на основе параметров NOT-NULL, которые пользователь передал в URL.Поскольку у меня есть 4 параметра, все возможности приводят к 16 различным запросам (так как у меня также есть метод findAll, который выводит все результаты, когда параметры не определены), и создавать их все время скучно.

Мой контроллер:

@RequestMapping(value = "/countries", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity listCountries(
        @RequestParam(value = "name", required = false) String name,
        @RequestParam(value = "twoLetterCode", required = false) String twoLetterCode,
        @RequestParam(value = "threeLetterCode", required = false) String threeLetterCode,
        @RequestParam(value = "nameInPortuguese", required = false) String nameInPortuguese) {
    try {

        List<Country> countryList = null;

        @Autowired
        private CountryRepository countryRepository;

        if (name != null && !name.isEmpty() && !name.equals("")) {
            if (twoLetterCode != null && !twoLetterCode.isEmpty() && !twoLetterCode.equals("")) {
                if (threeLetterCode != null && !threeLetterCode.isEmpty() && !threeLetterCode.equals("")) {
                    if (nameInPortuguese != null && !nameInPortuguese.isEmpty() && !nameInPortuguese.equals("")) {
                        countryList = countryRepository.findByNameTwoLetterCodeThreeLetterCodeNameInPortuguese(name, twoLetterCode, threeLetterCode, nameInPortuguese);
                    } else {
                        countryList = countryRepository.findByNameTwoLetterCodeThreeLetterCode(name, twoLetterCode, threeLetterCode);
                    }
                } else {
                    if (nameInPortuguese != null && !nameInPortuguese.isEmpty() && !nameInPortuguese.equals("")) {
                        countryList = countryRepository.findByNameTwoLetterCodeNameInPortuguese(name, twoLetterCode, nameInPortuguese);
                    } else {
                        countryList = countryRepository.findByNameTwoLetterCode(name, twoLetterCode);
                    }
                }
            } else {
                if (threeLetterCode != null && !threeLetterCode.isEmpty() && !threeLetterCode.equals("")) {
                    if (nameInPortuguese != null && !nameInPortuguese.isEmpty() && !nameInPortuguese.equals("")) {
                        countryList = countryRepository.findByNameThreeLetterCodeNameInPortuguese(name, threeLetterCode, nameInPortuguese);
                    } else {
                        countryList = countryRepository.findByNameThreeLetterCode(name, threeLetterCode);
                    }
                } else {
                    if (nameInPortuguese != null && !nameInPortuguese.isEmpty() && !nameInPortuguese.equals("")) {
                        countryList = countryRepository.findByNameNameInPortuguese(name, nameInPortuguese);
                    } else {
                        countryList = countryRepository.findByName(name);
                    }
                }
            }
        } else {
            if (twoLetterCode != null && !twoLetterCode.isEmpty() && !twoLetterCode.equals("")) {
                if (threeLetterCode != null && !threeLetterCode.isEmpty() && !threeLetterCode.equals("")) {
                    if (nameInPortuguese != null && !nameInPortuguese.isEmpty() && !nameInPortuguese.equals("")) {
                        countryList = countryRepository.findByTwoLetterCodeThreeLetterCodeNameInPortuguese(twoLetterCode, threeLetterCode, nameInPortuguese);
                    } else {
                        countryList = countryRepository.findByTwoLetterCodeThreeLetterCode(twoLetterCode, threeLetterCode);
                    }
                } else {
                    if (nameInPortuguese != null && !nameInPortuguese.isEmpty() && !nameInPortuguese.equals("")) {
                        countryList = countryRepository.findByTwoLetterCodeNameInPortuguese(twoLetterCode, nameInPortuguese);
                    } else {
                        countryList = countryRepository.findByTwoLetterCode(twoLetterCode);
                    }
                }
            } else {
                if (threeLetterCode != null && !threeLetterCode.isEmpty() && !threeLetterCode.equals("")) {
                    if (nameInPortuguese != null && !nameInPortuguese.isEmpty() && !nameInPortuguese.equals("")) {
                        countryList = countryRepository.findByThreeLetterCodeNameInPortuguese(threeLetterCode, nameInPortuguese);
                    } else {
                        countryList = countryRepository.findByThreeLetterCode(threeLetterCode);
                    }
                } else {
                    if (nameInPortuguese != null && !nameInPortuguese.isEmpty() && !nameInPortuguese.equals("")) {
                        countryList = countryRepository.findByNameInPortuguese(nameInPortuguese);
                    } else {
                        countryList = countryRepository.findAll();
                    }
                }
            }
        }


        if (countryList != null && !countryList.isEmpty()) {
            List<CountryDTO> dtosList = modelMapper.map(countryList, new TypeToken<CountryDTO>() {}.getType());
            return ResponseEntity(dtosList, HttpStatus.OK);
        } else {
            return ResponseEntity.status(HttpStatus.OK).body(new EmptySerializableClass());
        }

    } catch (Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    }

}

Мой репозиторий:

@Query("SELECT c FROM Country c WHERE c.name LIKE :name")
public List<Country> findByName(@Param("name") String name);

@Query("SELECT c FROM Country c WHERE c.twoLetterCode LIKE :twoLetterCode")
public List<Country> findByTwoLetterCode(@Param("twoLetterCode") String twoLetterCode);

@Query("SELECT c FROM Country c WHERE c.threeLetterCode LIKE :threeLetterCode")
public List<Country> findByThreeLetterCode(@Param("threeLetterCode") String threeLetterCode);

@Query("SELECT c FROM Country c WHERE c.nameInPortuguese LIKE :nameInPortuguese")
public List<Country> findByNameInPortuguese(@Param("nameInPortuguese") String nameInPortuguese);

@Query("SELECT c FROM Country c WHERE c.name LIKE :name AND c.twoLetterCode LIKE :twoLetterCode")
public List<Country> findByNameTwoLetterCode(@Param("name") String name, @Param("twoLetterCode") String twoLetterCode);

@Query("SELECT c FROM Country c WHERE c.name LIKE :name AND c.threeLetterCode LIKE :threeLetterCode")
public List<Country> findByNameThreeLetterCode(@Param("name") String name, @Param("threeLetterCode") String threeLetterCode);

@Query("SELECT c FROM Country c WHERE c.name LIKE :name AND c.nameInPortuguese LIKE :nameInPortuguese")
public List<Country> findBynameInPortuguese(@Param("name") String name, @Param("nameInPortuguese") String nameInPortuguese);

@Query("SELECT c FROM Country c WHERE c.twoLetterCode LIKE :twoLetterCode AND c.threeLetterCode LIKE :threeLetterCode)")
public List<Country> findByTwoLetterCodeThreeLetterCode(@Param("twoLetterCode") String twoLetterCode, @Param("threeLetterCode") String threeLetterCode);

@Query("SELECT c FROM Country c WHERE c.twoLetterCode LIKE :twoLetterCode AND c.nameInPortuguese LIKE :nameInPortuguese")
public List<Country> findByTwoLetterCodeNameInPortuguese(@Param("twoLetterCode") String twoLetterCode, @Param("nameInPortuguese") String nameInPortuguese);

@Query("SELECT c FROM Country c WHERE c.threeLetterCode LIKE :threeLetterCode AND c.nameInPortuguese LIKE :nameInPortuguese")
public List<Country> findByThreeLetterCodeNameInPortuguese(@Param("threeLetterCode") String threeLetterCode, @Param("nameInPortuguese") String nameInPortuguese);

@Query("SELECT c FROM Country c WHERE c.name LIKE :name AND c.twoLetterCode LIKE :twoLetterCode AND c.threeLetterCode LIKE :threeLetterCode)")
public List<Country> findByNameTwoLetterCodeThreeLetterCode(@Param("name") String name, @Param("twoLetterCode") String twoLetterCode, @Param("threeLetterCode") String threeLetterCode);

@Query("SELECT c FROM Country c WHERE c.name LIKE :name AND c.twoLetterCode LIKE :twoLetterCode AND c.nameInPortuguese LIKE :nameInPortuguese")
public List<Country> findByNameTwoLetterCodeNameInPortuguese(@Param("name") String name, @Param("twoLetterCode") String twoLetterCode, @Param("nameInPortuguese") String nameInPortuguese);

@Query("SELECT c FROM Country c WHERE c.name LIKE :name AND c.threeLetterCode LIKE :threeLetterCode AND c.nameInPortuguese LIKE :nameInPortuguese")
public List<Country> findByNameThreeLetterCodeNameInPortuguese(@Param("name") String name, @Param("threeLetterCode") String threeLetterCode, @Param("nameInPortuguese") String nameInPortuguese);

@Query("SELECT c FROM Country c WHERE c.twoLetterCode LIKE :twoLetterCode AND c.threeLetterCode LIKE :threeLetterCode AND c.nameInPortuguese LIKE :nameInPortuguese")
public List<Country> findByTwoLetterCodeThreeLetterCodeNameInPortuguese(@Param("twoLetterCode") String twoLetterCode, @Param("threeLetterCode") String threeLetterCode, @Param("nameInPortuguese") String nameInPortuguese);

@Query("SELECT c FROM Country c WHERE c.name LIKE :name AND c.twoLetterCode LIKE :twoLetterCode AND c.threeLetterCode LIKE :threeLetterCode AND c.nameInPortuguese LIKE :nameInPortuguese")
public List<Country> findByNameTwoLetterCodeThreeLetterCodeNameInPortuguese(@Param("name") String name, @Param("twoLetterCode") String twoLetterCode, @Param("threeLetterCode") String threeLetterCode, @Param("nameInPortuguese") String nameInPortuguese);

@Query("SELECT c FROM Country c")
public List<Country> findAll();

Итак, вы, ребята, поняли, о чем мой вопрос,Вместо того, чтобы создавать эти миллионы if / else и тысячи запросов для обработки ненулевых параметров, определенных в вызове URL, есть способ в Spring Framework - или даже в JPA / Hibernate - написать только один запрос, который обнаружит эти ненулевыепараметры и поиск по ним (а если все параметры нулевые, то просто вернуть все результаты)?

Ответы [ 2 ]

0 голосов
/ 28 мая 2019

спасибо всем, но я мог это сделать! Это было просто так:

@Query("SELECT c FROM Country c WHERE (:name is null or c.name LIKE :name)"
+ " AND (:twoLetterCode is null or c.twoLetterCode LIKE :twoLetterCode)"
+ " AND (:threeLetterCode is null or c.threeLetterCode LIKE :threeLetterCode)"
+ " AND (:nameInPortuguese is null or c.nameInPortuguese LIKE :nameInPortuguese)")

public List<Country> findCountries(
@Param("name") String name, 
@Param("twoLetterCode") String twoLetterCode,
@Param("threeLetterCode") String threeLetterCode,
@Param("nameInPortuguese") String nameInPortuguese);
0 голосов
/ 17 мая 2019

Вы не можете сделать это с @Query аннотациями.Но вы можете использовать Query by Example или Specification.

С Query by Example вы создаете экземпляр вашей целевой сущности Country, который содержит значения фильтра в качестве атрибутов и null для тех, которые не должны фильтроваться.,Также укажите ExampleMatcher, который управляет типом сравнения (равенство, содержит, регистр не учитывается и т. Д.).

Подробности см. В документации .

Еще более гибкими являются спецификации, в которых вы создаете условие «где» программно с помощью API критериев JPA или, альтернативно, с помощью Querydsl.

Снова в документации описываются подробности .

...