728x90
QueryDSL이란?
QueryDSL은 JPA를 보완하는 강력한 쿼리 생성 프레임워크이다.
JPQL(Java Persistence Query Language)을 자바 코드로 작성할 수 있게 해주며, 컴파일 시점에 SQL 문법 오류를 잡아낼 수 있는 큰 장점이 있다.
필자는 SQL과 JPQL을 문자열로 작성하는 대신, 자바 코드로 작성함으로써 타입 안전성을 보장받을 수 있다는 점에서 놀랍게 다가왔던 것 같다.
QueryDSL의 필요성?
그렇다면 QueryDSL이 왜 필요할까?
QueryDSL을 사용하기 전과 후로 나누어보자!
사용하기 전:
데이터베이스 쿼리를 작성할 때 기존의 방식들은 몇 가지 한계점이 있었다.
순수 JPA를 사용할 떄는 문자열로 쿼리를 작성해야 했기 때문에 실수하기 쉽고, 오타가 있어도 컴파일 시점에 발견할 수 없었다.
또한 동적 쿼리 작성 시 복잡한 if문을 사용해야 했기 때문에 코드가 매우 복잡해졌다.
사용하기 후:
자바 코드로 쿼리를 작성하기 때문에 IDE의 자동완성 기능을 사용할 수 있고, 컴파일 시점에 오류를 발견할 수 있다.
또한 메서드 체이닝을 통해 직관적이고 깔끔한 코드를 작성할 수 있다.
QueryDSL 설정해보기
QueryDSL을 사용하기 위해서는 먼저 build.gradle에 다음과 같은 설정이 필요하다.
plugins {
id 'java'
id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
}
dependencies {
implementation 'com.querydsl:querydsl-jpa:5.0.0'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0'
}
이 설정을 통해 QueryDSL이 엔티티 클래스를 기반으로 Q클래스를 자동으로 생성한다.
QueryDSL 기본 문법 알아보기
그렇다면 QueryDSL의 기본적인 쿼리 작성 방법을 살펴보자.
public List<Member> findMembersByUsername(String username) {
return queryFactory
.selectFrom(member)
.where(member.username.eq(username))
.fetch();
}
위 코드는 회원의 이름으로 검색하는 간단한 쿼리이다.
member는 자동 생성된 QMember 클래스의 인스턴스라고 보면 된다.
동적 쿼리 작성 예시도 살펴볼까?
public List<Member> searchMembers(String username, Integer age) {
return queryFactory
.selectFrom(member)
.where(
usernameEq(username),
ageEq(age)
)
.fetch();
}
private BooleanExpression usernameEq(String username) {
return username != null ? member.username.eq(username) : null;
}
private BooleanExpression ageEq(Integer age) {
return age != null ? member.age.eq(age) : null;
}
이 예제는 동적 쿼리를 매우 깔끔하게 작성할 수 있음을 보여준다.
조건문이 null이면 해당 조건은 무시된다.
더 복잡한 조인 쿼리 예시도 있다.
public List<MemberTeamDto> searchByBuilder(MemberSearchCondition condition) {
return queryFactory
.select(new QMemberTeamDto(
member.id,
member.username,
member.age,
team.id,
team.name))
.from(member)
.leftJoin(member.team, team)
.where(
usernameEq(condition.getUsername()),
teamNameEq(condition.getTeamName()),
ageGoe(condition.getAgeGoe()),
ageLoe(condition.getAgeLoe())
)
.fetch();
}
이 예제는 회원과 팀을 조인하고, DTO로 직접 조회하는 복잡한 쿼리를 보여주는데,
QueryDSL을 사용하면 이러한 복잡한 쿼리도 타입 안전(Type Safe)하게 작성할 수 있다.
728x90
'Spring' 카테고리의 다른 글
[Spring] JPA와 Spring Data JPA가 뭘까??? (0) | 2025.01.20 |
---|---|
[Spring] MyBatis 개념정리 🤩 (0) | 2025.01.20 |
[Spring] JdbcTemplate으로 데이터베이스 접근하기! (0) | 2025.01.20 |
[Spring] 🔎 DataSource와 트랜잭션 개념정리 🔎 (2) | 2025.01.20 |
[Spring] Controller의 Return Type과 Parameter 가이드 👍 (1) | 2025.01.20 |