1 분 소요


목차

  • 동적 쿼리 해결
    • BooleanBuilder
    • Where 다중 파라미터 사용
  • 수정, 삭제 벌크 연산
  • SQL function


동적 쿼리 해결

동적 쿼리를 해결하는 두 가지 방식

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

BooleanBuilder

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

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

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

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

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

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

Where 다중 파라미터

@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 queryFactory
            .selectFrom(member)
            .where(usernameEq(usernameCond), ageEq(ageCond))
            .fetch();
}

private Predicate usernameEq(String usernameCond) {

    if(usernameCond == null) {
        return null;
    }else{
        return member.username.eq(usernameCond);
    }
}

private Predicate ageEq(Integer ageCond) {

    if (ageCond == null) {
        return null;
    }else{
        return member.age.eq(ageCond);
    }
}
  • where 조건에 null값은 무시된다.
  • 메서드를 다른 쿼리에서도 재활용 할 수 있다.
  • 쿼리 자체의 가독성이 높아진다.


수정, 삭제 벌크 연산

대량 데이터 수정

long count = queryFactory
        .update(member)
        .set(member.username, "비회원")
        .where(member.age.lt(28))
        .execute();

기존 숫자에 1더하기

long count = queryFactory
        .update(member)
        .set(member.age, member.age.add(1))
        .execute();

곱하기 : multiply(x)

대량 데이터 삭제

long count = queryFactory
        .delete(member)
        .where(member.age.gt(18))
        .execute();

[주의] : JPQL과 마찬가지로, 영속성 컨텍스트에 있는 엔티티를 무시하고 실행되기 때문에 배치 쿼리를 실행하고 나면 영속성 컨텍스트를 초기화 하는 것이 안전하다.


SQL function

SQL function은 JPA와 같이 Dialect에 등록된 내용만 호출할 수 있다.

member -> M으로 변경하는 replace 함수 사용

String result = queryFactory
        .select(Expressions.stringTemplate("function('replace', {0}, {1}, {2})"
                        .member.username, "member", "M"))
        .from(member)
        .fetchFirst();

lower 같은 ansi 표준 함수들은 querydsl이 상당부분 내장하고 있기 때문에 다음과 같이 처리해도 된다.

.where(member.username.eq(member.username.lower()))


<출처 : 인프런 - 실전! Querydsl(김영한)>

댓글남기기