본문 바로가기
JPA

Querydsl - 3편

by 성건희 2022. 2. 15.
반응형

Null, 빈 값 체크

Spring 에서 제공하는 StringUtils.hasText() 를 사용하면 된다.

if (StringUtils.hasText(condition.getUsername())) {

}

StringUtils isEmpty Deprecated

String 을 null 체크, 빈 값 체크하기 위해 StringUtils.isEmpty() 를 사용했으나,
Deprecated 되었길래 대안을 찾아보았다.

  • String 타입이라면 hasLength 또는 hasText 를 사용하라.
  • Object 타입이라면 ObjectUtils 의 isEmpty 를 사용하라.

BooleanBuilder 로 동적 쿼리를 만들 때 주의할 점

MemberSearchCondition condition = new MemberSearchCondition();
condition.setAgeGoe(35);
condition.setAgeLog(40);
condition.setTeamName("teamB");

List<MemberTeamDto> result = memberJpaRepository.searchByBuilder(condition);

위 처럼 검색을 위한 dto 를 만들어 두고, BooleanBuilder 를 사용해 동적 쿼리를 만들 수 있다.

참고 : 위에서 as 로 필드 이름을 맞춰주었는데, 생성자를 사용하므로 필드 이름을 맞추지 않아도 동작한다.
즉, member.id 만 적으면 된다.

여기서 주의 할 점은 위처럼 조건을 위해 DTO 에 값이 있으면 괜찮지만,
아래와 같이 DTO 의 조건이 없도록 설정한다면 모든 데이터를 DB 에서 가져오므로 성능에 문제가 있을 수 있다.

MemberSearchCondition condition = new MemberSearchCondition();

List<MemberTeamDto> result = memberJpaRepository.searchByBuilder(condition);

따라서 default 조건을 만들어 두거나, 페이징으로 처리하는 것이 좋다.

where 절 파라미터로 동적 쿼리 처리하기

BooleanBuilder 보다 깔끔하고 재사용이 가능하다는 장점이 있다.
where 절 조건 메서드를 만들 때 반환 타입을 Predicate 가 아닌 BooleanExpression 으로 하는 것을 추천한다.
자세한 내용은 Querydsl - 2편 을 참조

Spring Data JPA 에서 동적 쿼리 처리하기

사용자 정의 리포지토리를 만들어서 넣어주면 된다.

  1. custom interface 를 만든다.
  2. impl 로 인터페이스를 구현한다. (메서드 명에 impl 을 붙여야함에 주의)
  3. JPA Repository 에 custom interface를 extends 한다.

참고 : 핵심 비즈니스 로직으로 재사용 성이 높은 경우에는 JpaRepository 에 구현하고,
공용성이 없고 특정 API 에 종속되어 있는 경우에는 custom 보다는 별도로 조회용 repository 를 구현하는 것이 좋다.
(ex ) MemberQueryRepository)

Querydsl 페이징 처리

fetchResults() 의 경우 content 와 전체 카운트를 한번에 조회할 수 있다. (쿼리 2번 호출)

fetchCount, fetchResults 둘 다 Depreated 인데, 작성한 select 쿼리를 기반으로 count 쿼리를 만들어낸다.
그런데 이 기능이 select 구문을 단순히 count 처리하는 것으로 바꾸는 것이라,
단순한 쿼리에서는 잘 동작하는데, 복잡한 쿼리에서는 잘 동작하지 않는다.
그래서 명확하게 카운트 쿼리를 별도로 작성하고 fetch() 를 사용하여 해결해야한다.

참고 : groupby having절 사용시 fetchCount(), fetchResults() 사용 가능 여부 - 인프런 | 질문 & 답변

페이징 CountQuery 최적화

PageableExecutionUtils.getPage() 로 최적화

  • 스프링 데이터 라이브러리가 제공
  • count 쿼리가 생략 가능한 경우 생략해서 처리
    • 페이지 시작이면서 컨텐츠 사이즈가 페이지 사이즈보다 작을 때
    • 마지막 페이지 일 때 (offset + 컨텐츠 사이즈를 더해서 전체 사이즈 구함)

참고 : fetchResults, fetchCount 는 Deprecated 이므로,
위처럼 별도로 count 쿼리를 작성하고 fetchOne 으로 가져오면 된다.

참고

반응형

'JPA' 카테고리의 다른 글

JPA DB 컬럼 네이밍 문제  (0) 2023.09.05
SpringBoot 3.0 에서의 Querydsl 적용  (0) 2023.08.31
Querydsl - 2편  (0) 2022.02.08
Querydsl - 1편  (0) 2022.02.08
JPA 를 공부하면서 알게 된 내용 정리 4  (0) 2022.02.05

댓글