본문 바로가기
개념 공부/Spring & ORM

[Java / querydsl] querydsl로 동적쿼리를 처리하기

by clean01 2025. 3. 18.

동적 쿼리를 해결하는 2가지 방법

  • BooleanBuilder
  • Where 다중 파라미터 사용

 

(1) BooleanBuilder 방식

BooleanBuilder를 만들어서 querydsl의 where절에 넣어주기만 하면된다.

BooleanBuilder를 만들 때, 한 조건이 null이면 해당 조건을 빼도록 구현한다.

따라서 usernameParam을 null로 두었을 때는, JPQL의 where절에 age만 존재하고,

    @Test
    public void dynamicQuery_boolean_builder() {
        String usernameParam = null;
        Integer ageParam = 10;

        List<Member> result = searchMember1(usernameParam, ageParam);
        Assertions.assertThat(result.size()).isEqualTo(2);
    }

    private List<Member> searchMember1(String usernameParam, Integer ageParam) {
        BooleanBuilder builder = new BooleanBuilder();

        if(usernameParam != null) {
            builder.and(member.username.eq(usernameParam));
        }

        if(ageParam != null) {
            builder.and(member.age.eq(ageParam));
        }

        return queryFactory.selectFrom(member).where(builder).fetch();
    }

 

 

두 조건 모두 null이 아닐 때는 where절에서 username, age를 모두 비교하는 것을 볼 수 있다.

    @Test
    public void dynamicQuery_boolean_builder() {
        String usernameParam = "member1";
        Integer ageParam = 10;

        List<Member> result = searchMember1(usernameParam, ageParam);
        Assertions.assertThat(result.size()).isEqualTo(1);
    }

    private List<Member> searchMember1(String usernameParam, Integer ageParam) {
        BooleanBuilder builder = new BooleanBuilder();

        if(usernameParam != null) {
            builder.and(member.username.eq(usernameParam));
        }

        if(ageParam != null) {
            builder.and(member.age.eq(ageParam));
        }

        return queryFactory.selectFrom(member).where(builder).fetch();
    }

 

 

(2) Where 다중 파라미터 활용

querydsl의 where절에 다중파라미터를 넣어 여러 조건을 처리할 수 있다.

아래 코드와 같이, 조건이 없을 때는 null을, 조건이 있을 때는 조건이 일치하는지 여부를 리턴해주는 메서드를 만들고

그 메서드를 where절에 파라미터로 넣어주면 다중 조건을 처리할 수 있다. (파라미터가 null이라면 그 조건은 무시된다.)

    private List<Member> searchMember2(String usernameCond, Integer ageCond) {
        return queryFactory
                .selectFrom(member)
                .where(usernameEq(usernameCond), ageEq(ageCond))
                .fetch();
    }

    private Predicate usernameEq(String usernameCond) {
        return usernameCond == null ? null : member.username.eq(usernameCond);
    }

    private Predicate ageEq(Integer ageCond) {
        return ageCond == null ? null : member.age.eq(ageCond); 
    }

 

 

동적 쿼리에서의 querydsl의 장점

querydsl의 진정한 장점은, 여러 동적쿼리 조건을 조합할 수 있고 재활용할 수 있다는 것이다.

아래 코드는 이름을 비교하는 메서드인 usernameEq, 나이를 비교하는 메서드인 ageEq를 각각 만들어, isSame이라는 메서드 안에서 and 조건을 조합한 예시이다.

이 isSame을 querydsl 코드의 where 조건 안에 넣으면, 이름과 나이가 같은 사람을 조회하는 쿼리가 나가지만, where절 안에 긴 코드가 들어가는 것보다 훨씬 가독성이 좋다.

그리고 이렇게만든 isSame 메서드는 다른 querydsl where절 안에서 재활용도 가능하다.

    private List<Member> searchMember2(String usernameCond, Integer ageCond) {
        return queryFactory
                .selectFrom(member)
                .where(isSame(usernameCond, ageCond))
                .fetch();
    }

    private BooleanExpression usernameEq(String usernameCond) {
        return usernameCond == null ? null : member.username.eq(usernameCond);
    }

    private BooleanExpression ageEq(Integer ageCond) {
        return ageCond == null ? null : member.age.eq(ageCond);
    }

    private BooleanExpression isSame(String usernameCond, Integer ageCond) {
        return usernameEq(usernameCond).and(ageEq(ageCond));
    }

 

 

Reference

인프런 < 실전! Querydsl (김영한) >