JPA/QueryDSL

[QueryDSL] 검색조건 ( where )

IT록흐 2023. 8. 7. 15:20
반응형
 

[QueryDSL] Expression( 표현 )

[QueryDSL] QueryDSL 동작원리(3) - fetch QueryDSL은 JPQL 생성 및 실행 권한을 자신에게 위임하여, 개발자가 JPQL을 직접 작성했을 때 발생하는 타입 안정성 체크의 어려움이나 동적 쿼리생성 문제를 해결할

lordofkangs.tistory.com

 

 

지난 포스팅에서 Expression을 다루어 보았다. 

이번 포스팅에서는 where 메소드의 매개변수로 어떤 Expression이 들어가는지 알아보겠다. 

 

QueryDSL 코드

    public List<Member> searchMember(MemberSearchCondition condition){
        return queryFactory
                .select(member)
                .from(member)
                .leftJoin(member.team, team)
                .where( //WHERE 메소드
                        usernameEq(condition.getUsername()),
                        teamNameEq(condition.getTeamName()),
                        ageGoe(condition.getAgeGoe()),
                        ageLoe(condition.getAgeLoe())
                )
                .fetch();
    }

 

QueryDSL은 JPQL 생성및실행을 담당하는 프레임워크이다. 개발자(클라이언트)가 원하는 JPQL을 QueryDSL에게 요청하려면 적절한 조건을 '표현'(Expression)해야 한다. '표현'(Expression)이라고 말한 이유는 QueryDSL이 실제로 클라이언트가 원하는 JPQL을 Expression 인터페이스로  표현할 수 있도록 환경을 제공하고 있기 때문이다.

 

where 메소드의 매개변수로 들어가는 표현을 '검색조건'이라고 부르는데, 여기에는 여러가지가 있다. 

 

member.username.eq("member1") // 표현 : username이 member1과 동일한가?
member.username.ne("member1") // 표현 : username이 member1과 동일하지 않은가?
member.username.eq("member1").not() // 표현 : username이 member1과 동일하지 않은가?
member.age.in(10, 20) // 표현 : 회원의 나이가 10,20 중에 있는가?
member.age.notIn(10, 20) // age not in (10, 20) // 표현 : 회원의 나이가 10,20 없는가?
member.age.between(10,30) //between 10, 30 // 표현 : 회원의 나이가 10과 30 사이에 있는가?
member.age.goe(30) // 표현 : 회원의 나이가 30보다 크거나 같은가?
member.age.gt(30) // 표현 : 회원의 나이가 30보다 큰가?
member.age.loe(30) // 표현 : 회원의 나이가 30보다 작거나 같은가?
member.age.lt(30) // 표현 : 회원의 나이가 30보다 작은가?
member.username.isNotNull() // 표현 : 회원의 이름이 Null이 아닌가?
member.username.like("member%") // 표현 : 회원의 이름이 member로 시작하는가?
member.username.contains("member") // 표현 : 회원의 이름에 member가 포함되는가?
member.username.startsWith("member") // 표현 : 회원의 이름이 member로 시작하는가?

 

위에 제시된 메소드들은 모두 Expression 인터페이스의 구현체를 반환하여, WHERE절 검색조건을 '표현'한다. 검색조건은 True/False를 나타내야 하기에,  Expression 인터페이스의 구현체로 BooleanExpression을 반환한다. 

 

eq 메소드 ( BooleanExpression 반환 )

public BooleanExpression eq(T right) {
	// 중략 ...
}

 

BooleanExpression 추상클래스

public abstract class BooleanExpression extends LiteralExpression<Boolean> implements Predicate {
	// 중략 ...
}

 

BooleanExpression은 Predicate의 구현체이다. 그럼 Predicate를 확인해보자.  

 

Predicate 인터페이스

public interface Predicate extends Expression<Boolean> {

    Predicate not();

}

 

Predicate 인터페이스는 Boolean 타입을 제네릭으로 하는 Expression 인터페이스를 상속한다. 고로, BooleanExpression은 Boolean을 제네릭으로하는 Expression 인터페이스의 구현체라고 할 수 있다. 

 

그럼 where 메소드를 확인해보자. 

 

// 검색조건이 하나인 경우
public Q where(Predicate o) {
    return queryMixin.where(o);
}

// 검색조건이 여러 개인 경우
public Q where(Predicate... o) {
    return queryMixin.where(o);
}

 

where 메소드를 보면 매개변수로 Predicate 인터페이스 구현체를 받는 것을 확인할 수 있다. 검색조건이 많은 경우, 가변 인자로 매개변수를 받는데, 이는 WHERE절의 AND와 같은 의미이다. 

 

이렇듯, 클라이언트는 QueryDSL에게 원하는 JPQL WHERE절을 표현하기 위해, Predicate의 구현체인 BooleanExpression을 반환하는 Expression으로 표현하여 매개변수로 전달한다. 표현이 되는 원리가 궁금하다면 지난 포스팅을 참고하면 된다.

 

 


 

참고자료

 

실전! Querydsl - 인프런 | 강의

Querydsl의 기초부터 실무 활용까지, 한번에 해결해보세요!, 복잡한 쿼리, 동적 쿼리는 이제 안녕! Querydsl로 자바 백엔드 기술을 단단하게. 🚩 본 강의는 로드맵 과정입니다. 본 강의는 자바 백엔

www.inflearn.com

 

반응형