Today I Learned
QueryDSL
#QueryDSL이란?
QueryDSL은 자바 코드로 SQL처럼 쿼리를 작성할 수 있게 해주는 프레임워크다.
JPA와 함께 사용하면 복잡한 조건 검색도 타입 안정성을 유지하며 구현할 수 있다.
JPQL의 문자열 기반 쿼리보다 안전하고 IDE 자동완성도 지원된다.
#QueryDSL의 사용 목적
조건이 유동적인 검색 로직을 깔끔하게 처리할 수 있다.
컴파일 시점에 오류를 잡을 수 있어 안정성이 높아진다.
여러 조건을 조합해도 가독성이 유지된다.
페이징과 정렬을 함께 처리할 수 있다.
#QueryDSL 주요 기능
1. 기본 쿼리 작성
Q 클래스는 빌드 시 자동 생성된다.
selectFrom으로 테이블을 지정하고, where로 조건을 추가하면 된다.
QTodo todo = QTodo.todo;
List<Todo> todos = queryFactory
.selectFrom(todo)
.where(todo.weather.eq("맑음"))
.fetch();
2. 동적 조건 처리
BooleanBuilder를 사용하면 조건이 있을 때만 추가할 수 있다.
null 체크로 유연한 검색이 가능해진다.
BooleanBuilder builder = new BooleanBuilder();
if (weather != null) {
builder.and(todo.weather.eq(weather));
}
3. 페이징 처리
QuerydslPredicateExecutor를 상속하면 findAll(Predicate, Pageable)로 페이징이 된다.
Page<Todo> result = todoRepository.findAll(builder, pageable);
4. 커스텀 Repository 구현
JPAQueryFactory를 사용하면 복잡한 조건과 페이징을 한 번에 처리할 수 있다.
offset과 limit으로 페이지를 나누고, count 쿼리로 전체 개수를 구하면 된다.
List<Todo> content = queryFactory
.selectFrom(todo)
.where(builder)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(todo.modifiedAt.desc())
.fetch();
#마치며
처음엔 QueryDSL이 복잡하게 느껴졌지만, 조건이 많아질수록 진가를 발휘한다는 걸 알게 되었다.
특히 BooleanBuilder를 활용한 동적 쿼리는 유지보수성과 확장성 모두를 잡을 수 있는 강력한 도구였다.
앞으로 검색 조건이 늘어날 프로젝트라면, QueryDSL을 미리 도입해두는 게 현명한 선택이 된다고 느꼈다.