% Like% Query в Spring JpaRepository


111

Я хотел бы написать подобный запрос, JpaRepositoryно он ничего не возвращает:

LIKE '%place%'-это не работает.

LIKE 'place' работает отлично.

Вот мой код:

@Repository("registerUserRepository")
public interface RegisterUserRepository extendsJpaRepository<Registration,Long> {

    @Query("Select c from Registration c where c.place like :place")
     List<Registration> findByPlaceContaining(@Param("place")String place);
}

Ответы:


200

Для запроса JPA с данными Spring требуются символы "%", а также пробел, следующие likeза вашим запросом, как в

@Query("Select c from Registration c where c.place like %:place%").

Ср http://docs.spring.io/spring-data/jpa/docs/current/reference/html .

Возможно, вы захотите полностью избавиться от @Queryаннотации, поскольку она кажется похожей на стандартный запрос (автоматически реализуемый прокси-серверами данных Spring); т.е. используя одну строку

List<Registration> findByPlaceContaining(String place);

достаточно.


23
Также может быть полезно игнорировать регистр для запроса, используя: findByPlaceIgnoreCaseContain (String place);
ilyailya

Как побочный комментарий - вы не можете смешивать и сопоставлять%: param% с% param% внутри одного запроса. Иначе приложение даже не запустится.
RVP

Спасибо. Раньше я писал like '%:place%'с помощью, 'и никаких результатов не было, потому что Hibernate сам добавляет 's к строкам.
Рион

Это не лучший ответ, но он также потенциально опасен. Spring разобрался с этим с помощью ContainIgnoreCase, проверьте мой ответ ниже.
Alexius DIAKOGIANNIS

100

Вам вообще не нужна @Queryаннотация.

Вы можете просто использовать следующие

    @Repository("registerUserRepository")
    public interface RegisterUserRepository extends JpaRepository<Registration,Long>{

    List<Registration> findByPlaceIgnoreCaseContaining(String place);

    }

Для меня это лучшее решение. Я не знал, что вы можете использовать IgnoreCase в сочетании с Contain, этого нет в документации.
Уилсон Кампусано

1
А как насчет случая, когда я хочу использовать много столбцов? - Я считаю, @Query()что это необходимо, правда? При таком подходе я должен был бы сделать orэто на самом деле не очень подходящее решение для этого случая:findByField1OrField2Containg(String phraseForField1, String phraseForField2)
user3529850

27

Вы также можете реализовать аналогичные запросы, используя ключевое слово «Содержит», поддерживаемое Spring Data JPA .

List<Registration> findByPlaceContaining(String place);

20

В вашем случае вы можете напрямую использовать методы JPA. Это похоже на ниже:

Содержит: select ... как%: place%

List<Registration> findByPlaceContainingIgnoreCase(String place);

здесь IgnoreCase поможет вам искать элемент без учета регистра.

Использование @Query в JPQL :

@Query("Select registration from Registration registration where 
registration.place LIKE  %?1%")
List<Registration> findByPlaceContainingIgnoreCase(String place);

Вот несколько связанных методов:

  1. подобно findByPlaceLike

    … Где x.place like? 1

  2. Начиная с findByPlaceStartingWith

    … Где x.place как? 1 (параметр связан с добавленным%)

  3. EndingWith findByPlaceEndingWith

    … Где x.place как? 1 (параметр связан с добавлением%)

  4. Содержащие findByPlaceContaining

    … Где x.place как? 1 (привязка параметра заключена в%)

Дополнительная информация, просмотрите эту ссылку , эту ссылку и это

Надеюсь, что это поможет вам :)


6

У вас может быть одна альтернатива использования заполнителей как:

@Query("Select c from Registration c where c.place LIKE  %?1%")
List<Registration> findPlaceContainingKeywordAnywhere(String place);

4

Попробуй это.

@Query("Select c from Registration c where c.place like '%'||:place||'%'")

Полезно, если мы используем something=:placeи another like %:place%в запросе.
hong4rc



0

Нашел решение без @Query(на самом деле я пробовал, какой из них "принят". Однако это не сработало).

Придется возвращаться Page<Entity>вместо List<Entity>:

public interface EmployeeRepository 
                          extends PagingAndSortingRepository<Employee, Integer> {
    Page<Employee> findAllByNameIgnoreCaseStartsWith(String name, Pageable pageable);
}

IgnoreCase часть имела решающее значение для достижения этого!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.