- 스펙
- JPA 스펙 구현
- 정렬과 페이징
- 동적 인스턴스와 @Subselect
검색을 위한 스펙
스펙(Specification)은 애그리거트가 특정 조건을 충족하는지 여부를 검사한다.
public interface Speficiation<T> {
public boolean isSatisfiedBy(T agg);
}
agg -> 검사 대상이 되는 애그리거트 객체
isSatisfiedBy() 메서드는 검사 대상 객체가 조건을 충족하면 true, 아니면 false 리턴
스펙조합
스펙의 장점은 조합에 있다.
두 스펙을 AND 연산자나 OR 연산자로 조합해서 새로운 스펙을 만들 수 있고, 조합한 스펙을 다시 조합해서 더 복잡한 스펙을 만들 수 있다.
JPA를 위한 스펙 구현
앞서 예로 보여준 리포티저리 코드는 모든 애그리거트를 조회한 다음에 스펙을 이용해서 걸러내는 방식을 사용했다.
-> 실행 속도에 문제가 있다.
실제 구현에서는 쿼리의 where 절에 조건을 붙여서 필요한 데이터를 걸러야 한다.
JPA -> CriteriaBuilder, Predicate을 사용
JPA 스펙 구현
Specification 구현 클래스 생성
Specification 구현 클래스를 개별적으로 만들지 않고 별도 클래스에 스펙 생성 기능을 모아도 된다.
*리포지터리 구현 기술 의존
도메인 모델은 구현 기술에 의존하지 않아야 한다.
그런데 JPA용 Specification 인터페이스는 toPredicate() 메서드가 JPA의 Root와 CriteriaBuilder에 의존하고 있으므로 사용하는 리포지터리 인터페이스는 이미 JPA에 의존하는 모양이 된다.
그렇다면 Specification을 구현 기술에 완전히 중립적인 형태로 구현해서 도메인이 구현 기술에 완전히 의존하지 않도록 만들어야 할까? 내 대답은 '아니오'
노력에 비해 실제 얻는 이점이 크지 않음.
페이징과 개수 구하기 구현
setFirstResult() -> 읽어올 첫 번째 행 번호를 지정
setMaxResult() -> 읽어올 행 갯수 지정
조회 전용 기능 구현
리포지터리는 애그리거트의 저장소를 표현하는 것으로서 다음 용도는 적합하지 않음.
- 여러 애그리거트를 조합해서 한 화면에 보여주는 데이터 제공
- 각종 통계 데이터 제공
->> 조회 전용 쿼리로 처리 해야 함.
조회 전용 모델을 만드는 이유는 표현 영역을 통해 사용자에게 데이터를 보여주기 위함이다.
하이버네이트 @Subselect
하이버네이트는 JPA 확장 기능으로 @Subselect를 제공
@Subselect는 쿼리 결과를 @Entity로 매핑할 수 있는 유용한 기능
@Immutable, @Subselect, @Synchronize 하이버네이트 전용 애노테이션 -> 테이블이 아닌 쿼리 결과를 @Entity로 매핑 가능.
@SubSelect로 조회한 @Entity 수정할 수 없다. -> @Immutable
'책' 카테고리의 다른 글
[DDD START!] 1장 도메인 모델 시작 (0) | 2020.07.04 |
---|---|
[DDD START!] 6장 응용 서비스와 표현 영역 (0) | 2020.07.01 |
[모던 자바 인 액션] 1장 (0) | 2020.06.26 |
[DDD START!] 4장. 리포지터리와 모델구현(JPA 중심) (0) | 2020.06.21 |
[켄트 벡의 구현 패턴] 4장 동기유발, 5장 클래스, 6장 상태 (0) | 2020.06.17 |