본문 바로가기

Spring Boot/Spring Data JPA

queryDsl 정리 및 예제

spring boot jpa를 사용하다보면 jpa에서 지원하는 기본적인 메서드 만으로

원하는 데이터를 못 들고 오는 경우가 빈번하게 있었을 것이다. (복잡한 쿼리문)

따라서 jpql을 필연적으로 사용할 수 밖에 없는데 jpql 특성상 복잡도가 올라가면 오타 및 오탈자가 발생하기 쉽다.

문제는 동적 쿼리의 경우 이를 어플리케이션 로딩 시점에서 잡아내지 못하고 런타임 도중 에러가 발생한다.

// jpql 예시
@Query("select p from Post p join fetch p.user u "
    + "where u in "
    + "(select t from Follow f inner join f.target t on f.source = :user) "
    + "or u = :user "
    + "order by p .createdAt desc")
List<Post> findAllAssociatedPostsByUser(@Param("user") User user, Pageable pageable);

 

이를 어느정도 해소하기 위해 기여하는 프레임워크가 query dsl이다.

jpa 뿐만 아니라 아래와 같은 다양한 언어를 지원해 준다고 한다.

http://querydsl.com/

 

 

 

QueryDsl 이란?

SQL, JPQL 을 java코드로 작성할 수 있도록 해주는 빌더 API 이고,

Entity 클래스와 매핑되는 QClass 라는 객체를 사용해서 쿼리를 실행한다.

 

아래와 같은 엄청난 장점이 존재한다

  1. 코드로 쿼리를 작성하게 되므로 컴파일 과정에서 문법 오류를 쉽게 발견할 수 있다.
  2. 동적 쿼리 작성이 편리하다
  3. 메서드 추출을 통해 재사용이 가능해진다
  4. 자동완성 등 IDE의 도움을 받을 수 있다

다만 spring data jpa와 같이 사용하기 위해 커스텀 레포지토리를 만들어 줘야하고 (impl도..)

따로 gradle 설정도 필요하여 귀찮다는 단점도 있다. 

Entity 수정시 빌드 전까지 QClass가 갱신이 되지 않아 오류로 처리된다는 것도 귀찮다.

 

 

 

QueryDsl 설정

설정 및 동작은 아래 블로그들을 참고하여 본인 환경에 맞게 찾아보자.

 

SpringBoot - Querydsl이란? 설정방법

JPQL 예시코드Spring Data JPA가 기본적으로 제공해주는 CRUD 메서드 및 쿼리 메서드 기능을 사용하더라도, 원하는 조건의 데이터를 수집하기 위해서는 필연적으로 JPQL을 작성하게 됩니다. 간단한 로

velog.io

 

 

QueryDSL 사용이유와 사용방법

들어가기에 앞서 실무에서 사용하다보면 복잡한쿼리도 많아지고 동적쿼리도 피치못하게 사용해야하는 경우가 생기기 마련이다. JPQL로도 충분히 문제를 해결할 수는 있지만 복잡하고 손이 많이

solidbasics.tistory.com

 

Gradle 7 KotlinDSL (build.gradle.kts) Querydsl 5 설정 - 인프런 | 고민있어요

Gradle 7 build 설정 (KotlinDSL)build.gradle.ktsimport com.ewerk.gradle.plugins.tasks.QuerydslCompile plugins { java id('org.springframework.boot') ...

www.inflearn.com

 

 

 

QueryDsl 다양한 사용 예제

 

실제로 queryDsl을 사용할때 고민한 내용들을 기록한다.

 

BooleanExpression

 

QueryDsl) BooleanExpression

BooleanBuilder와 BooleanExpression 모두 Querydsl 라이브러리에서 제공하는 기능으로, 쿼리를 동적으로 생성하기 위해 사용한다. // booleanBuilder QMember member = new QMember("member"); public List findAllMember(Integer class,

dwc04112.tistory.com

 

from절 sub query

 

QueryDSL) From 절 SubQuery를 쓰고싶어

querydsl은 from절 서브쿼리를 지원하지 않아 답답한 적이 많았는데 다음 방법으로 from절 서브쿼리를 사용해보자. 하이버네이트 @Subselect를 이용해서 서브 쿼리로 사용할 엔티티에 가상 view 처럼 사

dwc04112.tistory.com

 

sub query limit 1

 

queryDsl) subquery limit 1

시작하기 전 아쉽게도 (querydsl) 서브쿼리에서 limit 옵션은 동작하지 않는다 정확한 이유는 잘 모르겠지만 쿼리가 실행될때 JPQLSerializer를 사용하여 싱글쿼리 문자열이 빌드된다. 이 과정에서 sub qu

dwc04112.tistory.com

 

caseBuilder

 

querydsl 에서 case문 사용하기

query에서 case when문을 사용하는 것보다 어플리케이션에서 비즈니스 로직으로 처리되는 것이 권장되는 방법이다. query dsl 에서 case문은 select절, where절에서 사용이 가능하다. 아래는 간단한 사용법

dwc04112.tistory.com

 

 

관계가 없는 entity join

sub query

프로젝션으로 DTO로 조회 (@QueryProjection)

결과값을 entity로 조회 (주의점)

fetchOne과 fetchFirst의 차이

페이징 처리