SQL에서 LIKE % % 문법을 통해 해당 단어가 포함된 값들을 추출할 수 있다.
JPA에서도 해당 기능이 있다.
// 전달받은 유저네임이 부분적으로 포함되어 있는 유저엔티티들을 반환한다. (JPA가 알아서 해줌)
List<UserEntity> findByUsernameContaining(String username);
findByUsernameContaining는 Spring Data JPA의 쿼리 메서드(Query Method) 기능을 활용한 것으로, 메서드 이름만으로 JPQL 쿼리를 자동 생성합니다.
Containing 키워드를 사용하면 LIKE 검색을 수행하며, 자동으로 % 와일드카드를 추가해 쿼리를 생성합니다.
메서드 이름 파싱:
findByUsernameContaining(String username) → username 필드에 대해 문자열 포함 여부를 검색합니다.
Containing은 Spring Data JPA의 쿼리 생성 키워드입니다.생성되는 쿼리:
SELECT * FROM user_entity WHERE username LIKE '%{username}%';
username의 앞뒤에 %가 자동 추가됩니다. findByUsernameContaining("john") → username LIKE '%john%'.대소문자 구분:
기본적으로 대소문자를 구분합니다.
→ 대소문자 무시 검색을 원하면 ContainingIgnoreCase를 사용합니다.
List<UserEntity> findByUsernameContainingIgnoreCase(String username);
| 키워드 | 예시 메서드 | 생성되는 쿼리 |
|---|---|---|
Containing | findByTitleContaining(String title) | title LIKE '%title%' |
StartingWith | findByTitleStartingWith(String title) | title LIKE 'title%' |
EndingWith | findByTitleEndingWith(String title) | title LIKE '%title' |
Like | findByTitleLike(String title) | title LIKE {title} (직접 % 추가 필요) |
성능 이슈:
%keyword%는 풀 테이블 스캔을 유발할 수 있습니다.
→ 대량 데이터에서는 인덱스 활용이 어려워 성능 저하가 발생할 수 있습니다.
와일드카드 직접 제어:
Like 키워드를 사용하면 직접 %를 추가해야 합니다.
findByUsernameLike("%" + username + "%");
컬렉션 반환:
결과가 여러 개일 수 있으므로 List<UserEntity>를 반환 타입으로 지정합니다.
public interface UserRepository extends JpaRepository<UserEntity, Long> {
// username에 "john"이 포함된 모든 사용자 조회 (대소문자 구분)
List<UserEntity> findByUsernameContaining(String username);
// username에 "john"이 포함된 모든 사용자 조회 (대소문자 무시)
List<UserEntity> findByUsernameContainingIgnoreCase(String username);
// username이 "user"로 시작하는 사용자 조회
List<UserEntity> findByUsernameStartingWith(String prefix);
// username이 "admin"으로 끝나는 사용자 조회
List<UserEntity> findByUsernameEndingWith(String suffix);
}
Containing은 문자열 포함 검색을 간편하게 구현할 수 있게 해주는 Spring Data JPA의 강력한 기능입니다.