LIKE를 사용한 Spring JPA @Query


93

CrudRepository에서 사용자 이름이 입력 매개 변수와 같은 사용자 목록을 제공 할 수있는 메서드를 만들려고합니다 (시작할뿐만 아니라 포함). 나는 방법을 사용하려고했지만 "findUserByUsernameLike(@Param("username") String username)"Spring 문서에서 말했듯이이 방법은 " where user.username like ?1"와 같다. 사용자 이름에 포함 된 모든 사용자를 얻으려고 이미 말했듯이 나에게 좋지 않습니다.

메서드에 대한 쿼리를 작성했지만 배포되지도 않습니다.

@Repository
public interface UserRepository extends CrudRepository<User, Long> {

@Query("select u from user u where u.username like '%username%'")
List<User> findUserByUsernameLike(@Param("username") String username);
}

아무도 이것으로 나를 도울 수 있습니까?


4
containing인덱스의 이점을 얻기 위해 사용할 수 있습니다. docs.spring.io/spring-data/jpa/docs/1.4.3.RELEASE/reference/…

답변:


170

다음 접근 방식을 사용하십시오 (나에게 적합합니다).

@Query("SELECT u.username FROM User u WHERE u.username LIKE CONCAT('%',:username,'%')")
List<String> findUsersWithPartOfName(@Param("username") String username);

주의 : JPQL의 테이블 이름은 대문자로 시작해야합니다.


10
또는 WHERE UPPER(u.username) LIKE CONCAT('%',UPPER(:username),'%')대소 문자를 구분하지 검색 할 수 있습니다
브래드 메이스

솔루션을 사용하여 SQL-Injection이 가능합니까? (CONCAT 때문에 질문)
ramden

@ramden은 모두 @Param위생 처리되었으므로 아니요.
nurettin

다음과 같이 할 수 있습니다. : username 다음 .setParameter ( "username", "% foo %");
Matthew Daumen

설정 방법 .setParameter ( "username", "% foo %"); @MatthewDaumen
xuezhongyu01

120

메소드 이름에서 쿼리 작성을 사용하여 일부 키워드를 설명하는 표 4를 확인하십시오.

  1. Like 사용 : select ... like : username

    List<User> findByUsernameLike(String username);
  2. 시작 : 선택 ... like : username %

    List<User> findByUsernameStartingWith(String username);
  3. EndingWith : 선택 ... like % : username

    List<User> findByUsernameEndingWith(String username);
  4. 포함 : 선택 ... like % : username %

    List<User> findByUsernameContaining(String username);

당신이 찾고있는 답이 4 번 이라는 것을 주목하세요 . @Query를 사용할 필요가 없습니다.


정말 도움이되지만 Containing 키워드를 사용하려는 경우 대소 문자를 구분하지 않을 수도 있습니까? 문서에는 StringMatcher에 대해 언급 된 내용이 있습니다. ExampleMatcher를 사용하여 별도의 함수를 만들면 작동하는 것 같지만이 대 / 소문자 구분을 추가하기 위해 내 자신의 함수를 작성하지 않도록 메서드 이름에 어떻게 든 선언 할 수 있습니까?
V.

11
다음과 같이 필요한 경우 대소 문자를 무시할 수도 있습니다. List<User> findByUsernameContainingIgnoreCase(String username);
Robert

퍼센트 기호는 거꾸로 StartingWith: select ... like :username%되어 있어야 하고 EndingWith: select ... like %:username... 어쨌든 훌륭한 대답은 ... 받아 들여 져야합니다. 감사.
Alessandro

@Robert 나는 대문자로 된 열 데이터를 가지고 있으며 JPQL과 같은 방법을 사용하고 소문자 값을 전달하고 값을 가져올 수 있습니다. IgnoreCase 없이는 또한 부적절한 사례 데이터를 가져옵니다. 이 이상한 행동이 발생한 이유는 무엇입니까?
greenhorn

@greenhorn 별도의 StackOverflow 질문을 열고 테이블에 데이터 예제와 쿼리 대상을 추가하십시오.
Robert

25

다른 방법 : CONCAT함수 대신 이중 파이프를 사용할 수 있습니다. : lastname || '%'

@Query("select c from Customer c where c.lastName LIKE :lastname||'%'")
List<Customer> findCustomByLastName( @Param("lastname") String lastName);

어디에나 접두사, 접미사 또는 둘 다를 넣을 수 있습니다.

:lastname ||'%'  
'%' || :lastname  
'%' || :lastname || '%'  

10

List<User> findByUsernameContainingIgnoreCase(String username);

케이스 문제를 무시하기 위해


솔루션을 사용하여 SQL-Injection이 가능합니까?
xuezhongyu01


8

귀하의 경우에는 JPA 방법을 직접 사용할 수 있습니다. 그것은 다음과 같습니다.

포함 : 선택 ... like % : username %

List<User> findByUsernameContainingIgnoreCase(String username);

여기서 IgnoreCase 는 케이스를 무시하고 항목을 검색하는 데 도움이됩니다.

다음은 몇 가지 관련 방법입니다.

  1. 처럼 findByFirstnameLike

    … x.firstname like? 1

  2. 로 시작 findByFirstnameStartingWith

    … 여기서 x.firstname like? 1 (파라미터는 %가 추가됨)

  3. EndingWith findByFirstnameEndingWith

    … 여기서 x.firstname은? 1 (앞에 %가 붙은 매개 변수)

  4. 포함 findByFirstnameContaining

    … 여기서 x.firstname like? 1 (파라미터 경계가 %로 래핑 됨)

추가 정보, 이 링크이 링크보기

이것이 당신을 도울 것입니다 :)


감사! JPA 규칙을 사용하는 것은 올바른 방법처럼 느껴집니다.
FigletNewton

3

이 방법은 나를 위해 작동합니다 (Spring Boot 버전 2.0.1. RELEASE 사용).

@Query("SELECT u.username FROM User u WHERE u.username LIKE %?1%")
List<String> findUsersWithPartOfName(@Param("username") String username);

설명 :? 1,? 2,? 3 등은 첫 번째, 두 번째, 세 번째 매개 변수 등의 자리 표시 자입니다.이 경우 매개 변수를 표준 SQL 쿼리 인 것처럼 %로 둘러싸기에 충분하지만 작은 따옴표.


숫자 대신 명명 된 매개 변수를 선호해야합니다.@Query("SELECT u.username FROM User u WHERE u.username LIKE %:username%")
Ralph

0
@Query("select u from user u where u.username LIKE :username")
List<User> findUserByUsernameLike(@Param("username") String username);

감사합니다. deplouing의 문제는 jpql이 대소 문자를 구분한다는 것입니다. 이제 배포 중이지만 'LIKE'가 원하는대로 작동하지 않습니다. 입력 매개 변수와 완전히 동일한 레코드 만 찾습니다 (포함하지 않음).
Viktoriia

-1
@Query("select b.equipSealRegisterId from EquipSealRegister b where b.sealName like %?1% and b.deleteFlag = '0'" )
    List<String>findBySeal(String sealname);

이 코드를 시도했고 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.