Specifications (명세)
- Specifications (명세) : DB 쿼리의 조건을 조립해 간단한 Spec으로 작성해서 날릴 수 있게 해준다.
- 스프링 데이터 JPA는 JPA Criteria를 활용해서 기능을 지원해준다.
- 술어(predicate)로 이루어져 있다.
- JPA Criteria 기술을 사용하기에 직관적이지 못하고 실무에서는 사용하지 않는 기술이다.
대신 QueryDsl을 사용할 것...
- Predicate (술어) : 참 또는 거짓으로 평가되며 AND, OR 연산자를 조합해서 다양한 검색 조건을 쉽게 생성한다.
Query By Example
- Query By Example : 도메인 객체를 검색 조건으로 사용하는 방식이다.
//Query By Example 예제
//Probe 생성
Member member = new Member("m1");
Team team = new Team("teamA");
member.setTeam(team);
ExampleMatcher matcher = ExampleMatcher.matching().withIgnorePaths("age");
Example<Member> example = Example.of(member, matcher);
List<Member> result = memberRepository.findAll(example);
- Probe : 필드에 데이터가 있는 실제 도메인 객체
- ExampleMatcher : 특정 필드를 일치시키는 상세한 정보 제공
- Example : Probe와 ExmampleMatcher로 구성되며 쿼리를 생성하는데 사용한다.
- Query By Example 특징
- 장점
- 동적 쿼리를 편리하게 처리
- 도메인 객체를 그대로 사용
- RDB에서 NOSQL로 변경해도 코드 변경없이 추상화 되어 있다.
- JpaRepository에 이미 포함되어 있다.
- 단점
- 조인은 가능하지만 내부 조인만 가능하고 외부 조인은 불가능하다.
- 중첩 제약조건 사용 불가
- 매칭 조건이 단순
- 장점
- 실무에서 사용하기에는 매칭 조건이 단순하고 외부 조인이 안되기에 어렵다.
마찬가지로 QueryDsl을 사용할 것
Projections
- Projections : DB의 필요한 속성만을 조회하는 것.
- 엔티티 대신 DTO를 편리하게 조회할 수 있도록 도와주는 기능이다.
public interface UsernameOnly {
String getUsername(); //Closed Projection
@Value("#{target.username + ' ' + target.age}")
String getUsername2(); //Open Projection
}
public interface MemberRepository extends JpaRepository<Member, Long> {
List<UsernameOnly> findProjectionsByUsername(@Param("username") String username);
}
- 인터페이스에 메소드를 생성하고 JpaRepository를 상속하는 인터페이스에서 인터페이스를 반환타입으로 사용할 수 있다.
- 구현체는 스프링 데이터 JPA에서 프록시 기술을 통해서 만들어서 주입해준다.
- Closed Projection과 Open Projection으로 구분된다.
- Closed Projection은 지정한 속성만을 프로젝션하기에 가져오려는 속성이 무엇인지 먼저 파악이 가능하므로 쿼리 최적화가 가능하다.
- Open Projection은 @Value 어노테이션을 사용하며 target으로 지정된 속성을 조합해 새로운 반환 값으로 커스터마이징 할 수 있다.
- 이 경우 엔티티 필드를 다 조회해온 다음에 계산하기에 쿼리 최적화가 되지 않는다.
- 클래스 기반 Projection도 있다.
- 생성자의 파라미터 이름으로 매칭한다.
<T> List<T> findProjectionsByUsername(String username, Class<T> type);
- Generic을 통해 동적 Projection도 만들 수 있다.
- 프로젝션 대상이 Root 엔티티면 SELECT 절 최적화 가능
- Root가 아니라면 LEFT OUTER JOIN 처리를 하며 모든 필드를 SELECT해서 엔티티로 조회한 다음에 계산한다.
- Projection은 root 엔티티일 때 유용하다.
- 실무의 복잡한 쿼리를 해결하기에는 한계가 있다.
네이티브 쿼리
- JPA 사용 시 네이티브 쿼리는 가급적 사용하지 않는 것이 좋다.
@Query(value = "select * from member where username = ?", nativeQuery = true)
Member findByNativeQuery(String username);
- @Query 어노테이션에 직접 쿼리 작성 후 nativeQuery 속성을 true로 지정하면 된다.
- 스프링 데이터 JPA 기반 네이티브 쿼리
- 페이징 지원
- 반환 타입 - Object[], Tuple, DTO
- 제약 조건
- Sort 파라미터를 통한 정렬이 정상 작동x
- JPQL처럼 애플리케이션 로딩 시점에 문법 확인 불가
- 동적 쿼리 불가
- 네이티브 쿼리로 DTO 조회할 때는 JdbcTemplate 이나 MyBatis를 사용하는 것을 권장한다.
- 정적 네이티브 쿼리는 스프링 데이터 JPA의 Projection을 사용하는 것이 좋다.
출처 : [인프런 김영한 실전 스프링 데이터 JPA]
실전! 스프링 데이터 JPA 강의 | 김영한 - 인프런
김영한 | 스프링 데이터 JPA는 기존의 한계를 넘어 마치 마법처럼 리포지토리에 구현 클래스 없이 인터페이스만으로 개발을 완료할 수 있습니다. 그리고 반복 개발해온 기본 CRUD 기능도 모두 제
www.inflearn.com
'Spring > [인프런 김영한 실전 스프링 데이터 JPA]' 카테고리의 다른 글
[인프런 김영한 실전 스프링 데이터 JPA] 스프링 데이터 JPA 분석 (0) | 2024.09.12 |
---|---|
[인프런 김영한 실전 스프링 데이터 JPA] 확장 기능 (3) | 2024.09.11 |
[인프런 김영한 실전 스프링 데이터 JPA] 쿼리 메소드 기능 (1) | 2024.09.11 |
[인프런 김영한 실전 스프링 데이터 JPA] 공통 인터페이스 기능 (0) | 2024.09.10 |