인프런 커뮤니티 질문&답변

Hyeonuk Kim님의 프로필 이미지

작성한 질문수

QueryDSL에서 In 연산자를 사용해 복수개의 컬럼과 비교할때 서브쿼리 없이 쿼리를 생성하는 방법이 있나요?

24.01.09 23:22 작성

·

200

·

수정됨

0

안녕하세요.

QueryDSL에서 in 연산자를 사용해서 쿼리를 작성하려합니다.

문제 요약

  • 의도 : QueryDSL에서 In연산자를 사용해 비교하는 쿼리 작성하려함.

     

    • 비교대상 컬럼은 복수개 (in 연산자 좌항)

       

    • (동적으로 생성한) 리터럴 2차원 배열 (서브쿼리가 아님)

  • 문제 : 자꾸 첫째 항목에서 괄호가 사라짐...

  • 의문 : queryDSL

    방법을 잘못 쓴 것인지? 혹은 실제 QueryDSL이나 JPA의 오류인지 알고싶음.

     

 

상세 내용

작성하려는 쿼리는 입력된 복수개의 은행사와 계좌번호 쌍을 기준으로 계좌(BankAccount)엔티티의 정보를 검색하는 것입니다. 테이블에 "은행사,계좌번호" 쌍 중에 원하는 조합만 검색하는 게 목적입니다.

 

실제 데이터베이스에서 실행되길 의도한 쿼리

select 
    ba.*
from bank_account ba
where (ba.bank_name, ba.account_num ) in 
( /* 입력된 리스트에 따라 가변적으로 변하는 부분 */
  /* 아래 조합에만 일치하는 것만 검색 */
    ( '하나', '3333-444-555'),
    ( '국민', '4455-1111-44')
    /* 조합계속 ... */
)

 

따라서 아래와 같이 Expressions.list() 메소드로 IN절의 좌항을 완성하고 in의 파라미터로 서브쿼리 (서브쿼리가 들어가면 잘 동작함) 대신 리터럴 값을 넣어 생성했습니다.

QueryDSL에서 쿼리 생성 예시(민감정보 바꾸고 간소화함)

fun getBankAccountList( )
jpaQueryFactory.selectFrom(bankAccount)
    .where(
        Expressions.list(
            bankAccount.bank, //은행사
            bankAccount.accountNum, // 계좌번호
        ).`in`(
         /* 사용자로부터 입력받은 은행사,계좌번호 쌍들  */
            Expressions.list(
                Expressions.constant(BankName.HANA.value),
                Expressions.constant("1234-56-789"),
            ),
            Expressions.list(
                Expressions.constant(BankName.HANA.value),
                Expressions.constant("2345-67-890"),
            ),
            Expressions.list(
                Expressions.constant(BankName.WOORI.value),
                Expressions.constant("3333-33-333"),
            ),
        ) // in()
    ) // where()
.fetch()

실제로 생성된 쿼리를 보면 자꾸 2차원 배열의 첫째 항의 괄호가 사라집니다.

생성된 쿼리 예시

SELECT /*
컬럼 파트
*/
FROM 
    BANK_ACCOUNT B0_
WHERE
(
   B0_.BANK_NAME, B0_.ACCOUNT_NUM
) IN (
    '하나', '1234-56-789', // 여기 첫째 항목의 괄호가 없어짐..
   ( '하나', '1234-56-789'),
   ( '우리', '3333-33-333')
)

일단 다른 방법으로 기능 구현은 마친 상황입니다.

in 절이 본질적으로 각 항목과 컬럼을 동등비교하는 조건이 or연산자 기준으로 반복되는 것을 알고 있기에,
해당 방법으로 기능 자체는 구현은 했습니다.
(따라서 왜 괄호가 빠지는 것인지 자체에 대해 집중되었으면 하는 바람이 있습니다. )

 

그래서 의문사항은 다음 두가지 입니다.

  1. 이게 제대로된 queryDSL IN절 사용법이 아니라 그런 것일까요? 아니라면 옳은 방법은 뭘까요?

  2. 그냥 queryDSL 혹은 JPA의 이슈일까요?

     

 

환경

  • 언어 : 코틀린(1.5.31)

  • 자바버전 : 11

  • queryDSL : 5.0.0

  • springBoot : 2.5.6

 

답변 1

-1

인프런 AI 인턴님의 프로필 이미지

2024. 01. 10. 23:27

안녕하세요, 인프런 AI 인턴입니다.

HyeonukKim님께서 질문하신 QueryDSL의 IN 연산자 사용에 대한 문제 해결에 대해 답변드리겠습니다.

QueryDSL에서 튜플을 사용한 IN 조건을 구성할 때 괄호가 제대로 생성되지 않는 경우, 첫째로 문법 상의 오류는 아닐 가능성이 높습니다. 그러나, 현재 사용 중인 QueryDSL 버전에서 특정 구문을 지원하지 않거나 의도치 않게 생성되는 쿼리 형태로 인해 발생하는 문제일 수 있습니다. 이 경우, 공식 문서나 QueryDSL 관련 커뮤니티, 이슈 트래커를 통해 해당 문제에 대한 보고가 있는지 확인하는 것이 좋습니다.

QueryDSL의 공식적인 사용법과 관련된 정보는 업데이트된 버전의 문서를 참조하시는 것이 중요합니다. 또한, 복잡한 쿼리를 작성할 때는 항상 최신 버전을 사용하는 것이 좋은데, 현재 사용하고 계신 QueryDSL 5.0.0은 최신 버전으로 보이므로 이 부분은 문제가 없어 보입니다.

QueryDSL 또는 JPA에서 발생한 이슈일 수도 있습니다. 이 경우, 해당 프레임워크의 버그 트래킹 시스템에 문제를 제보하거나 커뮤니티를 통해 해결책을 찾아보는 것이 도움이 될 수 있습니다.

제안드릴 수 있는 몇 가지 해결 방법은 다음과 같습니다.

  1. 공식 문서 확인: 문제 해결을 위해 QueryDSL 관련 공식 문서를 참조하여 올바른 문법과 사용법을 확인하십시오.
  2. 이슈 트래킹: QueryDSL GitHub 또는 관련 포럼에서 유사한 문제를 경험한 다른 사용자의 해결 방법이나 제보를 찾아보십시오.
  3. 커뮤니티 문의: QueryDSL 관련 커뮤니티에 이슈를 공유하고 조언을 구하십시오.

지금 상황에서는 임시방편으로 OR 연산을 사용해서 문제를 해결하신 것처럼, 다른 방법을 모색해야 할 수도 있습니다. 이상의 내용이 HyeonukKim님의 문제 해결에 도움이 될 수 있기를 바랍니다.