
사실 이 기능들을 실무에서 잘 쓰지 않으니까 그냥 편하게 듣기
스프링 데이터 JPA는 JPA Criteria를 확용해 이 개념을 사용할 수 있도록 지원함
이 기능도 강사님은 실무에서 쓰지 못하도록 금지시키고 있음(하루만 지나도 읽을 수가 없음 ㅜ)
AND OR 같은 연산자로 조합해 다양한 검색조건을 쉽게 생성함(컴포지트 패턴으로)org.springframework.data.jpa.domain.Specification 클래스로 정의명세 기능을 사용하려면 JpaSpecificationExecutor 인터페이스를 상속받으면 된다.
Specification을 파라미터로 받아 검색 조건으로 사용한다.
Specification을 구현하면 명세들을 조립할 수 있다.
(where(), and(), or(), not() 제공)
findAll을 보면 (예제 상에서)회원 이름 명세(username)과 팀 이름 명세(teamName)를 and로 조합해 검색 조건으로 사용한다.
명세를 정의하려면 Specification 인터페이스를 구현
명세를 정의할 때는 toPredicate(...) 메소드만 구현하면 되는데 JPA Criteria의 Root, CriteriaQuery, CriteriaBuilder 클래스를 파라미터 제공
(예제에서는 편의상 람다를 사용)
⚠️ 실무에서는 JPA Criteria를 거의 쓰지 않는다! 대신 QueryDSL을 사용한다!

이전과 같이 쿼리를 하는데 Example에 의해 쿼리를 하겠다(?)
(그 옆에 age가 함께 설정되는 것은 ExampleMatcher를 생성해 무시시키면 됨)
Probe란 필드에 데이터가 있는 실제 도메인 객체ExampleMatcher는 특정 필드를 일치시키는 상세한 정보를 제공하며 재사용이 가능Example: Probe와 ExampleMatcher로 구성되었으며 쿼리를 생성하는데 사용JpaRepository) 인터페이스에 이미 포함 (repository를 받으면 그냥 쓸 수 있음)⚠️ 강사님은 조인이 안되면 실무에 도입하지 않는 편
firstname = ?0 or (firstname = ?1 and lastname = ?2)starts/contains/ends/regex=)만 지원 (equal 정도만 지원한다고 보면 됨)즉, 실무에서 사용하기엔 매칭 조건이 너무 단순하고 LEFT 조인이 안된다.
그냥 실무에서는 QueryDSL을 사용하자!
자꾸 똑같은 결론이 나는 강사님,,,
앞 기능들은 자꾸 도움이 안된다고 했는데 이건 그래도 좀 쓸모가 있어서 알아두면 좋음^^,,
엔티티 대신 DTO를 편리하게 조회할 때 사용한다.
예를 들어 전체 엔티티가 아니라 회원 이름만!! 조회하고 싶다면,, 🤷🏻♀️
회원 이름만 조회하고 싶다면 인터페이스에 getUsername()만 만들어놓으면 실제 구현체는 스프링 데이터 JPA가 만들어줌
조회할 엔티티의 필드를 getter 형식으로 지정하면 해당 필드만 선택해 조회(Projection)
➡️ 인터페이스에 추상화시킨 username만 정확하게 가져올 수 있게 되었음.
스프링 SpEL 문법 지원
⚠️ 단, SpEL 문법을 사용하면, DB에서 엔티티 필드를 다 조회해온 다음 계산한다. 따라서 JPQL SELECT 절 최적화가 안된다.
인터페이스가 아닌 구체적인 DTO 형식도 가능하다.
생성자의 파라미터 이름으로 매칭된다.
➡️ UsernameOnlyDto로 바꿔 돌린 결과
Generic type을 주면 동적으로 프로젝션 데이터를 변경할 수 있다.
📌 즉, 정리하자면
- 프로젝션 대상이 root 엔티티면 유용
- 프로젝션 대상이 root 엔티티를 넘어가면 JPQL SELECT 최적화가 안됨!!
- 실무의 복잡한 쿼리를 해결하기엔 한계
- 실무에서는 단순할 때만 사용, 조금만 복잡해지면 QueryDSL을 사용
어,,?
제약이 너무 많기 때문에 가급적 네이티브 쿼리는 사용하지 않는 것이 가장 좋다‼️ (정말 어쩔 수 없을 때만 사용하자,,)
최근에 나온 궁극의 방법 → 스프링 데이터 Projections 사용
JPQL은 위치 기반 파라미터를 1부터 시작하지만 네이티브 SQL은 0부터 시작
네이티브 SQL을 엔티티가 아닌 DTO로 변환하려면
@SqlResultSetMapping → 복잡