상속받지 않고 필요한 메소드만 직접 정의해서 구현해도 된다. JpaSpecificationExecutor를 살펴보면 다음과 같이 구현되어 있는 것을 볼 수 있다.
/** * Interface to allow execution of {@link Specification}s based on the JPA criteria API. * * @author Oliver Gierke * @author Christoph Strobl */publicinterfaceJpaSpecificationExecutor<T> { /** * Returns a single entity matching the given {@link Specification} or {@linkOptional#empty()} if none found. * * @param spec can be {@literal null}. * @return never {@literal null}. * @throwsorg.springframework.dao.IncorrectResultSizeDataAccessException if more than one entity found. */Optional<T> findOne(@NullableSpecification<T> spec); /** * Returns all entities matching the given {@link Specification}. * * @param spec can be {@literal null}. * @return never {@literal null}. */List<T> findAll(@NullableSpecification<T> spec); /** * Returns a {@link Page} of entities matching the given {@link Specification}. * * @param spec can be {@literal null}. * @param pageable must not be {@literal null}. * @return never {@literal null}. */Page<T> findAll(@NullableSpecification<T> spec,Pageable pageable); /** * Returns all entities matching the given {@link Specification} and {@link Sort}. * * @param spec can be {@literal null}. * @param sort must not be {@literal null}. * @return never {@literal null}. */List<T> findAll(@NullableSpecification<T> spec,Sort sort); /** * Returns the number of instances that the given {@link Specification} will return. * * @param spec the {@link Specification} to count instances for. Can be {@literal null}. * @return the number of instances. */longcount(@NullableSpecification<T> spec);}
JPA Criteria
JPA Criteria는 동적 쿼리를 사용하기 위한 JPA 라이브러리이다. 기본적으로 JPQL(JPA Query Language)과 같이 엔티티 조회를 기본으로 하며, 컴파일 시점에 에러를 확인할 수 있는 장점이 있다.
@Override @Transactional(readOnly =true)publicList<Payment>getPaymentRecentList(String mbrId,String succYn,Integer size) {// DynamicQuery로 succYn이 null이 아닌 경우에만 where 조건에 추가// Paging을 통해서 size(default 15)만큼만 최근(DESC) 데이터를 가져온다.Page<Payment> page=paymentRepository.findAll(newSpecification<Payment>() {privatestaticfinallong serialVersionUID =1L; @OverridepublicPredicatetoPredicate(Root<Payment> root,CriteriaQuery<?> query,CriteriaBuilder criteriaBuilder) {// TODO Auto-generated method stubList<Predicate> predicates =newArrayList<>();// where mbrId = ?predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get( "mbrId"), mbrId)));// 만약 성공여부(succYn)이 있는 경우에 조건 추가. null인 경 우 전체(Y/N) 조회 // where succYn = ?if(!StringUtils.isEmpty(succYn)) {predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get( "succYn"), succYn))); }returncriteriaBuilder.and(predicates.toArray(newPredicate[predicates.size()])); }// Jpa PageRequest를 사용해 size만큼 데이터 가져오기// 이때 pmtId(primary key)를 기준으로 내림차순(최근)데이터를 가져온다. },PageRequest.of(0, size,Sort.by(Sort.Direction.DESC,"pmtId"))); returnpage.getContent(); }
CriteriaBuilder 클래스를 통하여 조건문을 정의할 수 있고 정의된 스펙들은 조합하여 쓸 수 있다.