Spring Data JPA(쿼리 메소드)
Spring Data JPA로 쿼리를 생성하는 방법들을 알아보겠습니다.
• 메소드 이름으로 쿼리 생성
쿼리 메소드는 Repository 인터페이스에 간단한 네이밍 룰을 이용하여 메소드를 작성하면 원하는 쿼리를
실행할 수 있습니다.
쿼리 메소드를 이용할 때 가장 많이 사용하는 문법으로 find를 사용해보겠습니다.
엔티티의 이름은 생략이 가능합니다. find + (엔티티 이름) + By + 변수 이름
Spring Data JPA 기반 ItemRepository
ItemRepository 간단한 테스트
1. Item 엔티티 살펴보기
2. 쿼리 메소드 사용(간단하게 코드로 작성)
• 상품명 조회
List<Itrm> itemList = itemRepository.findByItemNm("AAA"); //상품명이 AAA인 것을 조회합니다
• 상품명 또는 상품 상세 설명 조회
List<Item> itemList = itemRepository.findByItemNmOrItemDetail("AAA","DDD") // 상품명이 AAA 또는
상품 상세가 DDD 인 것을 조회합니다. (인자 순서 주의)
• 가격이 10000원보다 작은 상품들 조회(가격_내림차순)
List<Item> itemList = itemRepository.findByPriceLessThanOrderByPriceDesc(10000); // 가격이 10000
원 보다 작은 상품들을 내림차순 정렬시킵니다.
다음 표에서는 JPA에 지원되는 키워드와 해당 키워드를 포함하는 메소드가 무엇으로 변환되는지 설명합니다. (공식문서 참조 https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods)
Distinct | findDistinctByLastnameAndFirstname | select distinct … where x.lastname = ?1 and x.firstname = ?2 |
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is, Equals | findByFirstname,findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull, Null | findByAge(Is)Null | … where x.age is null |
IsNotNull, NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection<Age> ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection<Age> ages) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstname) = UPPER(?1) |
• Named쿼리
Spring Data JPA 선언한 도메인 클래스 +.(점) + 메소드 이름으로 Named 쿼리를 찾아서 실행합니다. 만약 실행할 Named 쿼리가 없으면 메소드 이름으로 쿼리 생성 전략을 사용합니다.
3. Named 쿼리 사용해보기
앞에서 사용한 거와 같이 ItemRepositorty에 메소드를 추가해서 사용하면 된다.↗
List<Item> itemList = itemRepository.findByStockNumber(100); //재고 수량이 100개 이하인 것을 검색합니다
• @Query
앞에서는 한두 개 정도의 조건을 이용해서 쿼리 메소드를 사용하였습니다.
그런데 조건이 많아질 때 쿼리 메소드를 선언하면 이름이 정말 복잡하고 길어질 수 있습니다.
이를 보안하기 위하여 @Query 어노테이션 방법을 알아보겠습니다.
Spring Data JAP에서 제공하는 @Query 어노테이션을 이용하면 SQL과 유사한
JPQL(엔티티 객체를 대상으로 쿼리를 수행) 객체지향 쿼리 언어를 통해 복잡한 쿼리도 처리가
가능해집니다.
4. @Query 사용해보기
List<Item> itemList = itemRepository.findByItemDetail("DDD"); // 상품 상세 설명에 DDD가 포함되는 아이템 리스트를 내림차순으로 검색 완성된 쿼리문 -> ... from item where item_detail like '%DDD%' order by price desc;
지금까지 SPRING DATA JPA 쿼리 메서드의 3가지 기능을 알아보았습니다.
오류 없이 잘 실행이 되었지만 이 SPRING DATA JPA의 큰 장점은
애플리케이션 로딩 시점에 오류를 인지할 수 있다는 점입니다.