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

ykmykm4608님의 프로필 이미지

작성한 질문수

스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션

Jwt 필터 등록하기

JPQL 동적쿼리 부분 - > QUERYDSL 마이그레이션 후 질문

작성

·

384

0

querydsl설정은 각종 블로그 보고 설정 적용을 한상태입니다.

 

일단 엔티티 구조가

Transaction 엔티티에서

Accout 엔티티를 @MantToOne 다대일 단방향 매핑중이고,

입출금 내역 조회부분에서 jpql 부분을 그대로 챗 gpt 에 querydsl 기준 동적쿼리 코드를 돌려보면

이런 코드를 알려줍니다 우선 여기서

질문이

  1. WithdrawAccount, DepositAccount라는 클래스는 없고 Account를 참조 하는데 QWithdrawAccount, QDepositAccount Q클래스가 필요한 이유를 모르겠습니다.

저 코드를

해당 코드와 같이 바꿨습니다 그리고 테스트 코드를 돌려보면

 

transaction.withdrawAccount is not a root path 라는 에러가 나는데

root path 관련 질문글 찾아보면

" 이를 해결하려면 from 절에서 해당 객체를 다시 선언해주면 됩니다. 즉, querydsl에서는 join을 할 때 alias를 줘서 해당 객체를 다시 선언해주는 방식으로 작성해야 해결할 수 있습니다. "
이런 답변이있는데

변경 된 코드에서 innerjoin의 오른쪽 파라미터에 별칭을 잘못 줘서 에러가 나는거 같긴 한데

QTransaction.transaction.withdrawaccount 와 같은 별칭을 부여하면 안되는 걸까요,,?

답변 2

0

ykmykm4608님의 프로필 이미지
ykmykm4608
질문자

혹시 fetchjoin 적용 안된거 같은데 할필요가 없는걸까요?

 

  public List<Transaction> findTransactionList(Long accountId, String gubun, Integer page){

            JPAQuery<Transaction> query = jpaQueryFactory.selectFrom(transaction);

        return  query
                     .leftJoin(transaction.withdrawAccount).leftJoin(transaction.depositAccount)
                     .where(gubunCheck(gubun, accountId))
                     .limit(3).offset(page*3)
                     .fetch();

    }
    
    private BooleanExpression gubunCheck(String gubun, Long accountId){
        if (!StringUtils.hasText(gubun)){
            return
                    transaction.withdrawAccount.id.eq(accountId).or(transaction.depositAccount.id.eq(accountId));

        }else if(TransactionEnum.valueOf(gubun) == TransactionEnum.DEPOSIT){
            return
                    fetchjtransaction.depositAccount.id.eq((accountId));
        }else if(TransactionEnum.valueOf(gubun) == TransactionEnum.WITHDRAW){
            return
                    transaction.withdrawAccount.id.eq(accountId);
        }else {
            return null;
        }
    }
ykmykm4608님의 프로필 이미지
ykmykm4608
질문자


@Override
public List<Transaction> findTransactionList(Long accountId, String gubun, Integer page) {

    JPAQuery<Transaction> query = jpaQueryFactory.selectFrom(transaction);

    if ("WITHDRAW".equals(gubun)) {
            query
                .innerJoin(transaction.withdrawAccount, QAccount.account)
                .fetchJoin()
                .where(transaction.withdrawAccount.id.eq(accountId));
    } else if ("DEPOSIT".equals(gubun)) {
             query
                 .innerJoin(transaction.depositAccount, QAccount.account)
                 .fetchJoin()
                 .where(transaction.depositAccount.id.eq(accountId));
    } else { // gubun = alls
            query
                .leftJoin(transaction.withdrawAccount, QAccount.account)
                .leftJoin(transaction.depositAccount, QAccount.account)
                .where(transaction.withdrawAccount.id.eq(accountId)
                        .or(transaction.depositAccount.id.eq(accountId)));
    }

    return query
            .offset(page * 5)
            .limit(5)
            .fetch();
}

혹시 booleanexpression을 써야하나요?? 그리고 보여주신 링크는 좀 쿼리 자체가 달라서 jpql 쿼리부터,,

0

ykmykm4608님의 프로필 이미지
ykmykm4608
질문자

 

이렇게 하니 되네요,,? QAccout Q클래스가 맞았나 봅니다..,,

QAccount withdrawAccount = QAccount.account;
QAccount depositAccount = QAccount.account;
최주호님의 프로필 이미지
최주호
지식공유자

https://github.com/codingspecialist/JUNIT5-Security-Lecture/commit/04563b7813f8c8e51c7da4f05649f760f9079526

쿼리 DSL 적용된 커밋 로그입니다.

 

git clone 받아서

git reset --hard 0456

 

하면 코드 확인가능합니다.