////
Search
Duplicate

QueryDSL

QueryDSL이란?

하이버네이트 쿼리 언어의 쿼리를 타입에 안전하게 생성 및 관리해주는 프레임워크
정적 타입을 이용하여 SQL과 같은 쿼리를 생성할 수 있게 해준다.
Spring Data JPA를 사용하여 복잡한 쿼리 혹은 동적 쿼리를 구현하는데 한계가 있는데 이런 문제점을 해결할 수 있는 것이 QueryDSL이다.
QueryDSL이 등장하기 이전에는 Mybatis, JPQL, Criteria 등 문자열 형태로 쿼리문을 작성하여 컴파일 시에 오류를 발견하는 것이 불가능했다. 하지만 QueryDSL은 자바 코드로 SQL 문을 작성할 수 있어 컴파일 시에 오류가 발생하여 잘못된 쿼리가 실행되는 것을 방지할 수 있다.

QueryDSL의 장점

문자가 아닌 코드로 쿼리를 작성할 수 있어 컴파일 시에 에러를 확인할 수 있다.
IDE의 자동 완성 기능의 도움을 받을 수 있다.
복잡한 쿼리나 동적 쿼리 작성이 편리하다.
쿼리 작성 시 제약 조건 등을 메서드 추출을 통해 재사용 할 수 있다.
JPQL 문법과 유사한 형태로 작성할 수 있어 쉽게 적응할 수 있다.

설정

SpringBoot3.x + QueryDSL 5.0.0
build.gradle
설정을 아래와 같이 설정해준다.
dependencies 설정 추가
Q클래스가 생성될 경로 지정
따로 경로를 설정해주는 이유?
빌드 디렉토리에 생성되면 이 디렉토리를 직접 소스셋에 추가해야함
소스셋? :
소스셋(Source Set)이란 Gradle이 프로젝트 빌드를 진행할 때 참조하는 소스 코드와 리소스 파일들의 집합을 의미합니다.
예를 들어, Java 프로젝트에서는 'main'과 'test'라는 두 가지 기본 소스셋을 가지게 됩니다. 'main' 소스셋은 애플리케이션의 주요 소스 코드와 리소스들을 담고 있고, 'test' 소스셋은 테스트를 위한 소스 코드와 리소스들을 담고 있습니다.
각 소스셋은 소스 코드가 위치한 디렉토리와 그에 대응하는 컴파일된 클래스 파일들이 저장될 위치를 정의합니다. 이를 통해 Gradle은 프로젝트의 빌드 과정을 관리하게 됩니다.
따라서, Q 클래스의 생성 위치를 소스셋에 포함된 디렉토리로 설정해두면, 빌드 시에 자동으로 Q 클래스를 인식하고 컴파일할 수 있게 됩니다. 이는 추가적으로 소스셋을 설정해주는 작업을 줄여주므로 편리합니다.
빌드 디렉토리는 프로젝트 빌드 시 생성되는 중간 파일들이 저장되는 곳. 이 디렉토리의 내용은 clean작업 등으로 쉽게 삭제될 수 있음
팀원들이 Q클래스 파일을 더 쉽게 찾을 수 있음. 코드 관리 용이
config
프로젝트 전역에서 QueryDSL을 사용할 수 있도록 JPAQueryFactory를 Bean으로 등록해준다.
JPAQueryFactory의 역할? Querydsl을 사용하여 쿼리를 생성하고 실행하는 데 필요한 메서드를 제공하는 클래스. 빈으로 등록하면 어디서든 주입받아 사용할 수 있다.

Q클래스

JPAAnnotationProcessor가 컴파일 시점에 @Entity 어노테이션이 선언된 클래스에 대해 미리 생성하는 쿼리 객체
해당 객체에 쿼리문을 메서드 형태로 호출하여 SQL문을 짜듯이 코드로 쿼리문 작성이 가능하다.
도메인 클래스의 각 필드를 프로퍼티를 가지고 있으며 이 프로퍼티들은 쿼리 작성 시 사용된다.

사용

커스텀 인터페이스에 메서드 정의
커스텀 인터페이스를 구현하는 클래스에 QueryDSL 쿼리를 작
JpaRepository를 상속하는 Repository가 커스텀 인터페이스를 상속하도록 설정
구현클래스에 작성된 QueryDSL코드를 Repository가 사용할 수 있게 됨

BooleanExpression - 동적 조회

BooleanExpression은 QueryDSL에서 제공하는 클래스
SQL 또는 JPQL 쿼리에서 WHERE절에 해당하는 조건식을 표현하는데 사용됨
BooleanExpression은 null을 리턴할 경우 해당 조건문은 Where에서 제거된다.
null이 반환되면 조건이 제거되고 아니면 자동으로 조건이 적용된다는 기능을 통해 명시적인 쿼리문 작성이 가능하다.

BooleanBuilder 도 있는데?

동적쿼리를 작성할 때 사용하는 또다른 클래스
Booleanbuilder를 사용하여 이름과 나이로 멤버를 찾아주는 메서드 예제
public List<Member> findMembers(String name, Integer age) { BooleanBuilder builder = new BooleanBuilder(); if (!StringUtils.isEmpty(name)) { builder.and(QMember.member.name.eq(name)); } if (age != null) { builder.and(QMember.member.age.eq(age)); } return jpaQueryFactory .select(QMember.member) .from(QMember.member) .where(builder) .fetch(); }
Java
복사
위 코드처럼 if문으로 조건을 비교해서 BooleanBuilder객체에 값을 넣어주고 이 객체를 WHERE절에 넘겨주면 조건문이 완성된다.
하지만 반복적인 if문은 코드를 지저분하게 만들고 테이블의 필드 수가 많다면 if문은 더 늘어날 것.
이러한 이유 때문에 BooleanBuilder보다는 BooleanExpression 사용이 권장된다.

OrderSpecifier - 동적 정렬

QueryDSL에서 제공하는 클래스로, 쿼리 결과의 정렬 순서를 명시하는 데 사용된다.
SQL쿼리의 ORDER BY 절에 해당하는 기능을 수행한다.
정렬 방식은 asc 또는 desc를 사용하고, 정렬 대상 필드는 Q클래스의 프로퍼티를 사용한다.