[Querydsl] 동적쿼리

Welcome to Seoyun Dev Log·2023년 4월 28일
0

JPA

목록 보기
7/15

1. BooleanBuilder

  • 파라미터의 값이 null이냐 아니냐에 따라서 쿼리가 동적으로 바뀌어야 한다.

  • 📌 만약 username은 제외되지않고 필수로 들어가야한다면
    아래와 같이 builder에 넣어서 방어적 코드를 적성할 수 있다
    BooleanBuilder builder = new BooleanBuilder(member.username.eq(usernameCond));

  • 검색 조건으로 쓸 수 있다

  • BooleanBuiler에도 and, or 등의 메서드를 사용할 수 있다

@DisplayName("dynamicQuery_booleanBuilder")
    @Test
    void dynamicQuery_booleanBuilder() {
        String usernameParam = "member1";
        Integer ageParam = null;

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

    }

    private List<Member> searchMember1(String usernameCond, Integer ageCond) {
        //파라미터의 값이 null이냐 아니냐에 따라서 쿼리가 동적으로 바뀌어야 한다.

        BooleanBuilder builder = new BooleanBuilder();
        if (usernameCond != null) {
            builder.and(member.username.eq(usernameCond));
        }

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

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

2. where문의 다중 파라미터 사용

실무에서 추천하는 방법

  • where절에 null이 들어오는 경우에는 무시가 된다. (제외되는것)

where문 다운 파라미터를 사용하면

  • 쿼리 자체의 가독성이 높아진다
  • 메서드를 다른 쿼리에서도 재활용 할 수 있다.
  • 📌조합이 가능하다 : isVaild(서비스 가능한 상태인가?), Data IN (날짜 검색) -> isServiceAble() 메서드 하나로 만들어서 조합 가능
@DisplayName("dynamicQuery_whereParam")
    @Test
    void dynamicQuery_whereParam() {
        String usernameParam = "member1";
        Integer ageParam = 10;

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

    private List<Member> searchMember2(String usernameCond, Integer ageCond) {
        return jpaQueryFactory
                .selectFrom(member)
                .where(usernameEq(usernameCond), ageEq(ageCond))//where절에 null이 들어가면 무시된다.
                .fetch();
    }

    private Predicate usernameEq(String usernameCond) {
        if (usernameCond == null) {
            return null;
        }
        return member.username.eq(usernameCond);
		//삼항연산자
        //usernameCond != null ? member.username.eq(usernameCond) : null;
    }

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

  • 메서드 조합

    @DisplayName("dynamicQuery_whereParam")
       @Test
       void dynamicQuery_whereParam() {
           String usernameParam = "member1";
           Integer ageParam = 10;
    
           List<Member> result = searchMember2(usernameParam, ageParam);
           assertThat(result.size())
                   .isEqualTo(1);
       }
       
    	private List<Member> searchMember2(String usernameCond, Integer ageCond) {
           return jpaQueryFactory
                   .selectFrom(member)
                   .where(allEq(usernameCond, ageCond))
                   .fetch();
       }
       
       private BooleanExpression usernameEq(String usernameCond) {
           if (usernameCond == null) {
               return null;
           }
           return member.username.eq(usernameCond);
           //usernameCond != null ? member.username.eq(usernameCond) : null;
       }
    
       private BooleanExpression ageEq(Integer ageCond) {
           if (ageCond == null) {
               return null;
           }
           return member.age.eq(ageCond);
           //ageCond != null ? member.age.eq(ageCond) : null;
       }
    
       private BooleanExpression allEq(String usernameCond, Integer ageCond) {
           return usernameEq(usernameCond).and(ageEq(ageCond));
       }

profile
하루 일지 보단 행동 고찰 과정에 대한 개발 블로그

0개의 댓글