Query DSL 활용

Query DSL의 큰 장점 중 하나는 where 절에서의 null 처리이다.

 

여러 조건에 부합하는 결과를 조회해야 한다고 하자.

칸반 보드 프로젝트를 진행할 당시 상태와 담당자 닉네임을 필터링할 필요가 있었다.

그러나 해당 조건을 전부 받을 수도 있으나 담당자 닉네임 혹은 상태만 들어올 가능성도 있었다.

그러면 총 세 개의 Query 메서드를 작성해야 하나? 생각할 수도 있지만

Query DSL은 where 절에 null이 들어왔을 경우 알아서 where 문을 생략해 준다!

queryFactory.selectFrom(card)
    .where(card.board.id.eq(boardId)
            ,eqStatus(searchCond.getStatus())
            ,eqNickname(searchCond.getNickname()))
    .fetch();

 

 

(값을 받아올 때는 search cond를 사용하였다.)

참고로 where 절 안에서 ,를 사용해 조건을 추가할 때만 이 기능이 동작한다.

and를 사용해 조건을 추가할 때는 동작하지 않기 때문에 상황에 맞게 사용하자.

 

eqStatus와 eqNickname은 직접 만든 메서드인데 BooleanExpression를 반환한다.

조건이 참인지 거짓인지 판별하는 것이다.

private BooleanExpression eqStatus(String status){
    return StringUtils.hasText(status) ? card.status.title.eq(status) : null;
}

 

해당 메서드는 이렇게 생겼다.

String이 빈 값인지 아닌지 판단해서 BooleanExpression 혹은 null을 반환한다.

Query DSL이 null 조건을 무시할 수 있도록 말이다.

 

 

전체 코드

@Repository
@RequiredArgsConstructor
public class CardRepositoryQueryImpl implements CardRepositoryQuery{

    private final JPAQueryFactory queryFactory;

    @Override
    public List<Card> findBySearchCond(Long boardId, CardSearchCond searchCond){

        // 1. Board ID가 일치 해야 합니다.
        // 2. status 이름이 일치 해야 합니다.
        // 3. 담당자 nickname이 일치해야 합니다.

        /**
         * select *
         * from Card
         * where card.board.Id = boardId
         * and card.status.title = statusTitle
         * and card.User.nickname = nickname
         */

        return queryFactory.selectFrom(card)
                .where(card.board.id.eq(boardId)
                        ,eqStatus(searchCond.getStatus())
                        ,eqNickname(searchCond.getNickname()))
                .fetch();
    }

    private BooleanExpression eqStatus(String status){
        return StringUtils.hasText(status) ? card.status.title.eq(status) : null;
    }

    private BooleanExpression eqNickname(String nickname){
        return StringUtils.hasText(nickname) ? card.user.nickname.eq(nickname) : null;
    }

}

 

+ Recent posts