QueryDSL를 이용하여 Where 절 안에 IN 절을 사용해야 할 때가 있습니다. 단일 컬럼의 경우 QClass의 컬럼을 선택하고 .in() 메서드를 체이닝해서 처리를 하면 됩니다. 여러 개의 컬럼을 이용해야 할 경우 Expressions.list() 를 사용해서 컬럼 목록을 파라미터로 입력하고 .in() 메서드를 호출하면 됩니다. 이 때 in 메서드 안에 입력되는 값들은 다음과 같습니다.
public BooleanExpression in(Collection<? extends T> right)
public BooleanExpression in(T... right)
public BooleanExpression in(CollectionExpression<?,? extends T> right)
public BooleanExpression in(SubQueryExpression<? extends T> right)
public BooleanExpression in(Expression<? extends T>... right)
저는 다섯번째의 메서드를 사용하며, Expression<Tuple> 클래스 배열을 파라미터로 넣어주고 있습니다. Expression<Tuple> 클래스를 선택한 이유는 Expressions.template의 반환형이기 때문입니다.
IN 절의 데이터는 소괄호로 묶인 데이터가 입력이 돼야 합니다. QueryDSL은 이를 Expressions.template으로 표현을 할 수 있습니다.
다음은 예시 코드입니다.
final Expression<Tuple>[] tuples = new Expression[n];
for(int i=0; i<n; i++){
tuples[i] = Expressions.template(
Tuple.class,
"({0}, {1}, {2}, {3})",
#{0번째 데이터},
#{1번째 데이터},
#{2번째 데이터},
#{3번째 데이터}
);
}
위와 같이 Expressions.template을 호출하면 ({0}, {1}, {2}) 형태로 쿼리 바인딩에서 사용됩니다. IN 절에서 복수 개의 컬럼을 이용하여 조회를 할 때는 소괄호 안에 소괄호로 묶인 형태로 표현을 해야 하기 때문에 ({0}, {1}, {2}) 형태로 만들었습니다. 이렇게 사용하여 IN 쿼리를 사용하게 되면 다음과 같이 쿼리가 수행되는 것을 확인할 수 있습니다.
복수개의 데이터는 문제가 없습니다. 하지만 한 개의 데이터 묶음을 처리할 때는 다음과 같이 문제가 발생합니다.
앞서 설명드린 것과 같이 한 개의 데이터 묶음으로 조회를 하더라도 소괄호로 한 번 더 묶여야 합니다. ((?, ?, ?, ?)) 이런 형태로 말이죠.
코드로 수정하면 다음과 같으며 정상적으로 쿼리를 수행합니다.
Expressions.template(
Tuple.class,
"(({0}, {1}, {2}, {3}))",
...
);
https://programmingnote.tistory.com/87
'[개발] 프레임워크 > QueryDSL' 카테고리의 다른 글
[QueryDSL] LocalDateTime, LocalDate 파라미터 바인딩 시 'MM/dd/yyyy HH:mm:ss' 로 표시될 때 해결 방법 (1) | 2024.12.14 |
---|---|
[QueryDSL] projection으로 테이블 조인 결과 데이터 매핑하기 (0) | 2024.12.03 |
QueryDSL 셋팅 시 발생하는 에러 개선 (4) | 2024.11.14 |