🧩 Querydsl DynamicQuery

정의

Querydsl DynamicQuery조건에 따라 쿼리의 일부를 동적으로 조합하는 방식이다. 검색 조건, 정렬, 페이징, 그룹핑 등을 상황에 맞게 바꿔야 할 때 사용한다.

고정된 SQL보다 유연한 조회 로직이 필요할 때 유용하다.

🧩 역할

  • 조건을 동적으로 추가한다
  • 정렬 조건을 바꾼다
  • 페이징 적용 여부를 분기한다
  • from, groupBy 같은 절을 재사용한다

🛠 사용 예시

limit, offset 조건부 적용

JPAQuery<RobotList> query = queryFactory
        .select(qRobot)
        .from(qRobot)
        .leftJoin(qWork)
        .on(qRobot.lastExecuteWorkSequence.eq(qWork.workSequence))
        .where(getWhereClause(robotSearchForm))
        .orderBy(getOrderSpecifier(robotSearchForm.getSortKey(), robotSearchForm.getSortOrder()));

if (robotSearchForm.getPageRowCount() > 0) {
    query.offset(robotSearchForm.getStartRowNo2())
         .limit(robotSearchForm.getEndRowNo());
}

coalesce() 사용

qCustomer.age.coalesce(0).asNumber().sum()

from 절 재사용

private JPAQuery<?> getNewFromClauseWorkExecutionList(String summaryType) {
    JPAQuery<?> fromQuery = queryFactory
            .from(qTaskResultView)
            .leftJoin(qTaskProcess)
            .on(qTaskProcess.taskQueueSequence.eq(qTaskResultView.taskQueueSequence))
            .leftJoin(qWork)
            .on(qTaskResultView.workSequence.eq(qWork.workSequence));

    if ("RBT".equals(summaryType)) {
        fromQuery.innerJoin(qRobot)
                 .on(qTaskResultView.robotSequence.eq(qRobot.robotSequence));
    }

    return fromQuery;
}

groupBy 절 재사용

private Expression<?>[] getWorkExecutionListGroupByClause(WorkExecutionResultSearchForm form) {
    List<Expression<?>> groupByExpressions = new ArrayList<>();
    groupByExpressions.add(qWork.workSequence);
    groupByExpressions.add(qWork.workName);
    groupByExpressions.add(qTaskResultView.groupSequence);

    if ("RBT".equals(form.getSummaryType())) {
        groupByExpressions.add(qTaskProcess.taskQueueSequence);
        groupByExpressions.add(qRobot.robotSequence);
        groupByExpressions.add(qRobot.robotName);
    }

    return groupByExpressions.toArray(new Expression<?>[0]);
}

🧩 특징

  • 조건에 따라 쿼리 구조를 바꿀 수 있다
  • 재사용 가능한 쿼리 조각을 만들 수 있다
  • 페이징과 정렬을 분리해서 처리하기 좋다
  • Querydsl 표현식과 잘 맞는다

⚠️ 주의사항

  • 쿼리 조합이 많아지면 메서드가 길어질 수 있다.
  • null 조건은 별도 메서드나 BooleanExpression으로 분리하는 것이 좋다.
  • coalesce() 같은 함수는 DB 동작과 맞는지 확인해야 한다.
  • 재사용 메서드가 과도하게 많아지면 오히려 읽기 어려워질 수 있다.

📌 정리

  • Querydsl DynamicQuery는 조건에 따라 쿼리의 일부를 동적으로 바꾸는 방식이다.
  • 페이징, 정렬, 그룹핑, 조인 분기 등에 유용하다.
  • Querydsl의 표현식과 메서드 조합으로 복잡한 조회를 관리할 수 있다.

연결문서

댓글남기기