본문 바로가기
[개발] 프레임워크/QueryDSL

[QueryDSL] IN 절에 Expressions.template을 이용해서 데이터 넣기

by Devsong26 2024. 12. 31.
반응형

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

 

 

 

 

 

 

반응형