[QueryDSL] 중급 문법
1. 프로젝션
프로젝션 대상이 하나인 경우 대상 타입을 명확하게 지정할 수 있다.
제네릭스를 String으로 설정하고 값을 받아온다. (객체도 가능)
프로젝션 대상이 둘 이상인 경우 QueryDSL이 제공하는 Tuple 자료구조나 DTO를 따로 정의해서 반환값을 가져올 수 있다.
왼쪽은 Tuple을 사용하는 예시이다.
일단은 Tuple도 QueryDSL에 종속적인 타입이기 때문에, 바깥 계층으로 반환될 때를 생각하면 DTO를 사용하는 편이 합리적이다. (Repository 내부에서만 사용하는 경우는 괜찮다)
JPA를 사용할 때 DTO를 따로 정의해서 반환값을 가져오려면 new 명령어를 사용해 DTO의 생성자를 호출하는 방식을 사용해야 한다.
QueryDSL 기술을 사용하면 좀 더 간단하게 처리할 수 있다.
- Setter
MemberDTO 클래스에 Setter가 정의돼있어야 사용할 수 있다.
Projections의 bean을 사용해 Setter에 접근한다.
타입과 꺼내올 값을 지정해주면 된다.
- Field
Setter가 정의되어있지 않아도 괜찮다. 필드를 통해 주입된다.
필드가 private 으로 설정돼있어도 상관없다.
역시 타입과 꺼내올 값을 지정해주면 된다.
- Constructor
생성자를 사용할 때는 호출되는 생성자의 인자의 순서에 맞게 설정해야 한다.
생성자에 정의된 파라미터에 유의해서 사용하자.
데이터베이스 테이블에 있는 데이터명과 자바 객체에서의 변수명이 다른 경우 따로 처리해 줘야 한다.
필드에 별칭을 적용할 때는 as만 사용해도 괜찮지만, 서브쿼리에 별칭을 적용할 때는 ExpressionUtils의 as를 사용해야 한다. (필드에 ExpressionUtils의 as를 사용해도 상관없다)
2. QueryProjection
DTO를 정의할 때 생성자에 @QueryProjection 애너테이션을 붙이면 QueryDSL은 엔티티처럼 Q + DTO 객체를 만든다.
이 Q + DTO 객체를 사용해 DTO로 Projection을 좀 더 쉽게 처리할 수 있다.
@QueryProjection 과 위에서 사용한 그냥 생성자를 통해 Projection을 진행하는 작업의 차이는 실수 방지에 있다.
그냥 생성자를 통해 진행하는 경우 실수로 인자를 몇 개 더 추가하면 컴파일 시점에서 오류를 확인할 수 없지만, @QueryProjection을 사용해서 진행하는 경우 컴파일 시점에서 오류를 확인할 수 있다.
@QueryProjection을 사용하게 되면 MemberDTO에 QueryDSL 기술에 대한 의존성이 생기게 되는 단점도 있으니... 애플리케이션 설계 시 이 부분도 고려하도록 하자.
3. 동적 쿼리
QueryDSL에서는 동적 쿼리를 두 가지 방법으로 제공한다. 모두 살펴보자.
- BooleanBuilder
아주 직관적이다.
where 부분에 BooleanBuilder 객체를 전달하는 방식으로 작동하고, 입력에 따라 BooleanBuilder를 설정해준다.
- where 다중 파라미터
BooleanBuilder와 하는 역할은 같지만 코드가 좀 더 깔끔하다.
Predicate 또는 BooleanExpression 객체를 반환타입으로 설정하고, where 조건에 null 값은 무시되니 null 처리를 적절하게 사용해주자. (여러 메서드를 조합해서 쿼리를 작성할 때는 BooleanExpression을 사용해야 한다)
메서드를 다른 쿼리에서 재활용할 수 있다는 장점이 있다.
4. 벌크 연산
SQL 한 번으로 대량의 데이터를 수정할 때 사용한다.
나이가 28보다 작은 회원들은 이름을 비회원으로 변경하는 예시이다.
JPA를 공부할 때 확인했듯 벌크 연산을 사용하면 영속성 컨텍스트와 데이터베이스의 값이 일치하지 않게 되는 현상이 발생할 수 있으니 em.flush와 em.clear를 적절히 호출해주자.
'Spring > QueryDSL' 카테고리의 다른 글
[QueryDSL] 활용 (Spring Data JPA + QueryDSL) (1) | 2023.01.11 |
---|---|
[QueryDSL] 활용 (JPA + QueryDSL) (0) | 2023.01.11 |
[QueryDSL] 기본 문법 (0) | 2023.01.09 |
댓글
이 글 공유하기
다른 글
-
[QueryDSL] 활용 (Spring Data JPA + QueryDSL)
[QueryDSL] 활용 (Spring Data JPA + QueryDSL)
2023.01.11 -
[QueryDSL] 활용 (JPA + QueryDSL)
[QueryDSL] 활용 (JPA + QueryDSL)
2023.01.11 -
[QueryDSL] 기본 문법
[QueryDSL] 기본 문법
2023.01.09