728x90
QueryDSL 핵심 개념
| 항목 | 설명 |
| DSL 방식 | 쿼리를 자바 코드처럼 작성 가능 (where().and()) |
| 타입 안전 | 컴파일 타임에 필드, 테이블 오류 감지 가능 |
| 코드 자동 생성 | Q타입이라는 쿼리 객체 클래스 자동 생성됨 |
| JPQL 대체 | 문자열 없이 객체 기반으로 조건/정렬 작성 가능 |
1. 의존성 추가 (Gradle)
plugins {
id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
}
dependencies {
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'
annotationProcessor 'jakarta.annotation:jakarta.annotation-api'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api'
}
2. QueryDSL 설정 (build.gradle)
def querydslDir = "$buildDir/generated/querydsl"
querydsl {
jpa = true
querydslSourcesDir = querydslDir
}
sourceSets {
main.java.srcDir querydslDir
}
compileJava {
options.annotationProcessorGeneratedSourcesDirectory = file(querydslDir)
}
./gradlew clean build 실행 시 Q 접두사가 붙은 클래스가 자동 생성됨
예: QMember.java
3. 예제 Entity – Member
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
private int age;
@ManyToOne
private Team team;
}
QMember 자동 생성됨
4. 기본 사용 예제
조건 검색
@Repository
public class MemberQueryRepository {
private final JPAQueryFactory queryFactory;
public MemberQueryRepository(EntityManager em) {
this.queryFactory = new JPAQueryFactory(em);
}
public List<Member> findByUsername(String name) {
QMember member = QMember.member;
return queryFactory
.selectFrom(member)
.where(member.username.eq(name))
.fetch();
}
}
복합 조건 & 정렬
List<Member> result = queryFactory
.selectFrom(member)
.where(
member.age.goe(20),
member.username.contains("홍길동")
)
.orderBy(member.age.desc())
.fetch();
동적 쿼리도 가능
public List<Member> search(String name, Integer age) {
BooleanBuilder builder = new BooleanBuilder();
if (name != null) {
builder.and(member.username.eq(name));
}
if (age != null) {
builder.and(member.age.eq(age));
}
return queryFactory
.selectFrom(member)
.where(builder)
.fetch();
}
DTO 직접 조회 (Projections)
public List<MemberDto> fetchMemberDto() {
return queryFactory
.select(Projections.constructor(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
}
@QueryProjection을 사용하면 컴파일 시 타입 체크도 가능
QueryDSL vs JPQL 비교
| 항목 | JPQL | QueryDSL |
| 문법 | 문자열 기반 | 자바 메서드 체이닝 |
| 타입 안전성 | 없음 (런타임 오류) | 있음 (컴파일 타임 오류 체크) |
| 동적 쿼리 | 복잡함 (StringBuilder 등) | 매우 쉬움 |
| 학습 난이도 | 쉬움 | 약간 학습 필요 |
| 실무 사용성 | 제한적 | 고급 검색에 최적화 |
언제 QueryDSL을 사용할까?
| 상황 | 추천 |
| 단순 조회 | JPA 메서드 쿼리, @Query |
| 복합 조건 검색, 정렬 | QueryDSL |
| API 페이징, 검색 | QueryDSL + Pageable |
| 복잡한 JOIN, 서브쿼리 | QueryDSL 추천 |
마무리 요약
| 항목 | 설명 |
| 설정 | build.gradle에 QueryDSL + annotationProcessor 설정 |
| 핵심 클래스 | Q타입, JPAQueryFactory |
| 장점 | 컴파일 시점 오류 체크, 동적 쿼리, DTO 매핑 |
| 주의 | 코드 생성 후 Q클래스를 Git에 포함하거나 .gitignore 처리 |
LIST
'SpringBoot > 심화 주제' 카테고리의 다른 글
| 마이크로서비스 아키텍처(MSA) 입문 (1) | 2025.04.16 |
|---|---|
| 멀티모듈 프로젝트 구성 (0) | 2025.04.16 |
| WebSocket & 실시간 알림 (0) | 2025.04.16 |
| 캐시(Cache) (1) | 2025.04.16 |