JPA/QueryDSL

[QueryDSL] 공통으로 사용하는 표현 - LiteralExpression

IT록흐 2023. 8. 7. 21:21
반응형

 

 

[QueryDSL] Expression( 표현 )

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

lordofkangs.tistory.com

 

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으로 캐스팅 될 수 있다. 

 

 

 


 

 

참고자료 

 

[QueryDSL] String to Int, Varchar to Number (castToNum)

가끔 가다가 DB 설계가 이상하게 되어 있어서 Number 타입이었어야 하는 컬럼이 Varchar로 되어 있는 경우가 있다. 이런 경우 음 그냥 String을 Int로 바꿔서 쿼리하면 되는 거 아니야? 라고 생각이 드는

effortguy.tistory.com

 

실전! Querydsl - 인프런 | 강의

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

www.inflearn.com

 

반응형