2016-06-16 3 views
2

У меня есть таблица MySQL для клиентов, как это:JpaRepository с дополнительными параметрами

name | country | many more columns 
---------------------------------- 
John USA 
null France 
Max null 
null null 
... 

В моем приложении я хочу запросить эту таблицу. Пользователь может указать разные поля поиска, но не обязательно, чтобы каждое значение было задано. Я собираю запрос в классе репозитория, и я хочу игнорировать пустые параметры.

Пример, какие результаты ожидаются с несколькими параметрами поиска:

Name  | Country  Result 
-------------------------------- 
John  | (not set)  first table line 
(not set) | (not set)  all entries 
(not set) | a    line one and two (case insensitive) 

Я знаю, что могу создавать запросы, как:
findByNameAndByCountry(@Param("name") String name, @Param("country") String country);
, но в приложении У меня есть семь параметров поиска. Поскольку нет необходимости указывать их все, существует 128 различных запросов, которые я не хочу реализовывать.

Так что моя идея состояла в том, чтобы запросить базу данных, как это:

public interface CustomerRepository extends JpaRepository<Customer, java.lang.String> { 

    @Query("SELECT c FROM customer c WHERE " 
      + "(:name = '' OR c.name LIKE %:name%) " 
      + "AND (:country = '' OR c.country LIKE %:country%)") 
    List<Customer> findByParams(@Param("name") name, @Param("country") country); 

} 

Проблема заключается в том, это не работает. Если я только проверю параметр с LIKE, я не получу ожидаемых результатов, потому что '%' != null. Но мне также нужны записи базы данных с нулевыми значениями, если параметр поиска пуст. Я попытался проверить, пустой ли параметр с :param = '', но по какой-то причине это не работает.

Я также тестировал с IF(:param != '', c.param, '%') LIKE %:param% для каждого параметра, к сожалению, с тем же результатом.

Странная вещь, если я попробую эту команду непосредственно в моей базе данных, она работает нормально, но не с JpaRepository.

У кого-то есть идея, почему это не работает. Или есть лучшее решение для моей проблемы, о котором я не думал? Спасибо за каждую помощь :)

+0

Не используйте аннотацию Query, чтобы сделать это. Определите реализацию репозитория custome и используйте API критериев или QueryDSL для динамического составления запроса на основе параметров. –

+0

Спасибо, я рассмотрю вашу точку зрения. – Freddy

ответ

1

Попробуйте использовать правильный, как с помощью форматирования CONCAT

"SELECT c FROM customer c WHERE " 
     + "(:name = '' OR c.name LIKE concat('%', :name ,'%'') " 
     + "AND (:country = '' OR c.country LIKE concat ('%', :country, '%'')" 
+0

Большое спасибо! Вот и все. – Freddy