QueryDsl (Spring Boot 3.x ver.)
QueryDSL 이란?
DSL 은 Domain Specific Language의 약자로, 특정 영역에 특화된 언어를 의미하는데,
QueryDSL은 쿼리 생성에 특화된 프레임워크를 의미한다.
QueryDSL 사용 목적
JPA 프레임워크는 자동으로 SQL 쿼리문을 생성해 주어 SQL 관점 프로그래밍을 하지 않아도 된다.
Ex.
Optional<Comment> findByTodoIdAndId(Long todoId, Long commentId);
하지만 위와 같은 방식은 GROUP BY나 HAVING 등 복잡한 쿼리 생성이 불가능하기 때문에 이를 위해 JPQL을 지원한다.
하지만 JPQL에는 두 가지 단점이 있다.
- 타입 안정성이 떨어진다.
JPQL은 문자열이기 때문에 JPQL 문법이 틀려도 실행시키기 전까지는 오류를 발견할 수 없다.
컴파일 과정에서는 어떠한 오류도 발견할 수 없기 때문에 타입 안정성이 떨어진다. - 직관적인 동적쿼리 작성이 어렵다.
동적쿼리를 작성하려면 문자열을 조작하는 방식으로 로직을 구성하다 보니,
if - else 문이나 for 문 같은 코드가 들어가 가독성을 떨어뜨린다.
이러한 이유로 QueryDSL이 JPA가 지원하는 표준 기술이 아님에도 불구하고,
타입 안정성과 직관적인 동적쿼리 작성이 가능해 실무에서 JPA와 연계하여 가장 많이 사용되는 프레임 워크 중 하나이다.
QueryDSL이 JPQL을 생성할 수 있도록 필요한 데이터를 세팅하여 전달해야 한다.
QueryDSL은 쿼리 생성에 특화된 프레임워크로, JPA 프레임워크와 분리되어 있다.
그러나 Entity와 같은 JPA프레임워크에서 지원하는 모듈을 그대로 사용하게 되면, JPA프레임워크에 종속되어 버린다.
이것을 막고자 QueryDSL은 Entity 정보를 담은 Q 타입 클래스를 사용한다.
QueryDSL 작성예시
public List<Member> searchMember(MemberSearchCondition condition){
QMember qMember = QMember.member; //Q타입 클래스 객체 생성
return queryFactory
.select(qMember) // select 메소드
.from(qMember) // from 메소드
.leftJoin(member.team, team) // leftJoin메소드
.where( // where 메소드
usernameEq(condition.getUsername()),
teamNameEq(condition.getTeamName()),
ageGoe(condition.getAgeGoe()),
ageLoe(condition.getAgeLoe())
)
.fetch(); //fetch메소드
}
Method | 설명 |
fetch() | 반환값을 List 형식으로 가져옴 반환되는 데이터가 없으면 빈 리스트 반환 |
fetchOne() | 단 하나의 데이터를 조회 반환 데이터가 0개면 NULL, 2개 이상일 경우 NonUniqueResultException 발생 |
fetchFirst() | limit(1).fetchOne()과 동일하며, 항상 하나의 데이터만 조회 |
QueryDSL 환경 설정 (JPAQueryFactory ver.)
1. 의존성 주입
dependencies {
.
.
.
//QueryDSL 적용을 위한 의존성 (SpringBoot3.0 부터는 jakarta 사용해야함)
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}
2. Java 컴파일
1) gradle → other → compileJava 눌러서 build
2) Q 클래스 생성
3. JPAConfiguration 생성
@Configuration
public class JPAConfiguration {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
4. QueryRepository 생성
1) import QEntity
import static com.sparta.todocard.entity.QTodo.todo;
2) Query 작성
@Repository
@RequiredArgsConstructor
public class TodoQueryRepository {
private final JPAQueryFactory jpaQueryFactory;
public List<Todo> findByKeyword(String keyword) {
return jpaQueryFactory
.selectFrom(todo)
.where(
todo.title.contains(keyword)
.or(todo.content.contains(keyword))
.or(todo.user.username.contains(keyword))
)
.fetch();
}
}
3)
QueryDSL을 사용할 수 있는 Repository와 JPA 사용할 수 있는 Repository, 둘 다 사용 가능✨
'생활 > 내일배움캠프' 카테고리의 다른 글
내일배움캠프 40일차 TIL<JPQL & QueryDsl> (0) | 2025.07.17 |
---|---|
내일배움캠프 41일차 TIL<Java Lambda> (1) | 2025.07.17 |
내일배움캠프 42일차 TIL<AOP> (0) | 2025.07.17 |
내일배움캠프 45일차 TIL<FetchType.LAZY (지연로딩)> (0) | 2025.07.06 |
내일배움캠프 46일차 TIL<@RestControllerAdvice를 이용한 예외처리> (0) | 2025.07.06 |