QueryDSL은 JPQL 생성및실행을 담당하는 프레임워크이다. 개발자(클라이언트)가 원하는 JPQL을 QueryDSL에게 요청하려면 적절한 조건을 '표현'(Expression)해야 한다. '표현'(Expression)이라고 말한 이유는 QueryDSL이 실제로 클라이언트가 원하는 JPQL을 Expression 인터페이스로 표현할 수 있는 환경을 제공하고 있기 때문이다.
표현은 데이터 타입에 따라 분류된다.
수와 관련된 표현은 NumberExpression으로 표현된다.
queryFactory
.select(qProduct.price.avg()) // NumberExpression의 avg 메소드
.from(qProduct)
.fetch();
클라이언트가 상품의 평균 가격을 조회하는 JPQL 생성 및 실행을 원한다면 '조회된 상품의 평균 가격'을 표현해야 한다.
qProduct.price.avg() : '조회된 상품의 평균 가격'
NumberExpression은 avg메소드로 조회된 상품의 평균 가격을 '표현'한다. 이렇듯, 데이터 타입에 따라 데이터 타입 전용 표현을 담은 메서드가 존재한다.
NumberExpression : avg, add, abs ...
BooleanExpression : and, or, isTrue, isFalse ...
StringExpression : concat, charAt, contains, append ...
DateExpression : dayOfMonth, dayOfWeek, dayOfYear ...
EnumExpression : ordinal ...
이렇듯, 데이터에 따라 타입에 맞는 표현을 메소드 형태로 담은 Expression 클래스가 존재한다. 그렇다면 공통으로 사용되는 표현은 무엇이 있을까?
NumberExpression을 제외하고는, 거의 모두 LiteralExpression을 상속하고 있다. LiteralExpression은 '캐스팅(Casting)'을 표현한다.
castToNum
데이터타입은 Boolean, String, Date, Enum이지만 NumberExpression 전용 표현을 사용해야 하는 경우가 있다. 예를들어, DB에 나이(age)가 VARCHAR 타입으로 저장되어 있다면, 이는 StringExpression으로 표현된다. 그러나 나이는 숫자로, 수와 관련된 표현을 해야 하는 경우가 있다. 이런 경우 castToNum으로 캐스팅하여 표현하면 된다.
queryFactory.select(qPerson.ageA.castToNum(Integer.class).avg())
.from(qPerson)
.fetch();
위 코드와 같이, castToNum 메소드에 변경할 수의 클래스타입(Integer.class)을 매개변수로 넘기면 NumberExpression으로 캐스팅된다. 그러면 NumberExpression이 제공하는 표현을 사용할 수 있다.
stringValue
stringValue는 StringExpression으로 캐스팅하는 메소드이다.
queryFactory.selectFrom(qPerson)
.where(qPerson.birthDate.stringValue().like("2001%")
.fetch();
위 코드는 DateExpression을 StringExpression으로 캐스팅하고 생일이 2001년으로 시작한다는 검색조건을 표현한 코드이다.
이처럼 데이터 조작에 유용한 표현은 NumberExpression과 StringExpression이 가지고 있으니, LiteralExpression에 공통으로 사용하는 표현으로 Casting 메소드를 넣어 구현하였다. 참고로, LiteralExpression을 상속하지 않는 NumberExpression은 자체적으로 stringValue 메소드를 가지고 있다. 그러므로 NumberExpression도 stringValue 메소드로 언제든 StringExpression으로 캐스팅 될 수 있다.
참고자료
'JPA > QueryDSL' 카테고리의 다른 글
[QueryDSL] 공통으로 사용하는 표현 - ComparableExpressionBase (0) | 2023.08.08 |
---|---|
[QueryDSL] 결과조회 ( fetch ) (0) | 2023.08.07 |
[QueryDSL] 검색조건 ( where ) (0) | 2023.08.07 |
[QueryDSL] Expression( 표현 ) (0) | 2023.08.04 |
[QueryDSL] QueryDSL 동작원리(3) - fetch (0) | 2023.08.02 |