Hansel
QueryDsl 활용 1 본문
프로젝션

프로젝션은 데이터베이스의 관계대수에 나오는 개념이다.
실렉션은 수평적이고 프로젝션은 수직적이다.
다시말해 애트리뷰트의 부분 집합을 반환한다.
하나의 엔티티에서 프로젝션을 하더라도 다양한 타입의 결과가 반환될 수 있다.
사용법은 단순히 select절에 원하는 애트리뷰트를 기입하면 된다.
현재는 username만 가져오기 때문에 String만 반환하지만 만약 타입이 다른 다양한 값이 추가된다면,
그땐 튜플로 반환하게 된다.
튜플은 쿼리Dsl에서 사용하는 클래스로 이전에 언급했다.

2개 이상의 애트리뷰트를 프로젝션 연산하니 Tuple로 반환한다.
DTO 반환하기
쿼리DSl 이전에는 DTO를 생성하기 위해 데이터의 집합을 가져와 내부 stream을 돌리거나,
new 오퍼레이션을 사용해 DTO를 반환했다.
하지만 쿼리dsl은 세터, 필드, 생성자의 방식으로 바로 DTO 반환이 가능하다.
사용은 select 절에 Projections를 사용한다.
Setter (Projections.bean)

DTO에 setter가 있다면, 그 setter를 이용해 DTO를 생성해준다.
필드 주입 (Projections.fields)

세터와 입력 방식은 동일하다.
필드의 경우 setter가 필요하지 않다.
생성자 주입 (Projections.constructor)

주어진 파라미터에 맞는 생성자를 선택해 해당 생성자로 DTO를 생성한다.
DTO의 필드와 엔티티의 필드 명이 다르다면
이 경우엔 필드 명이 다른 필드에 .as() 메서드를 사용해 상이한 필드 명을 기입해주면 된다.

가장 간단한 QueryProjection
쿼리 프로젝션을 사용하면 해당 DTO를 쿼리dsl이 따로 생성해준다.
아래와 같이 해당 DTO의 생성자에 어노테이션을 추가해주고,
인텔리제이 기준 build, 그레이들 기준 gradlew clean compileJava를 해주면 Qdto가 생성된다.



select절에 따로 Projections를 사용할 필요 없이 new 오퍼레이션을 통해 바로 생성할 수 있다.
하지만 이 경우 문제가 생긴다.
DTO는 원래 쿼리Dsl에 의존적인 Dto가 아니었지만, 어노테이션이 추가되면서 의존성을 가져 결합도가 올라간다.
만약 추후에 쿼리Dsl을 사용하지 않게 된다면 관련된 부분을 모두 수정해주어야 한다.
동적쿼리
동적쿼리는 BooleanBuilder를 통해 생성하는 방식과 Predicate 인터페이스를 사용해 생성하는 방식이 있다.
Predicate은 쿼리dsl에서 불린 타입 비교를 위해 제공하는 인터페이스이다.

위 사진과 같이 불린빌더를 생성하고 and메서드를 사용해 boolean 조건을 추가해줄 수 있다.

builder는 and, or, not 등 다양한 메서드를 추가로 제공한다.
따라서 Booleanbuilder를 여러개 생성해 묶어줄 수 있다.
Predicate + where 절

이 방식의 장점은 where절에 오는 null을 유연하게 처리할 수 있다는 것이다.
또한 메서드 재활용도 가능하며, 쿼리 가독성도 훨씬 좋다.

추가로 위 사진과 같이 여러 조건을 조합해서 사용할 수 있다.
벌크연산

벌크연산은 update, delete 등의 연산을 다량으로 수행해야 할 때 사용된다.
쿼리Dsl의 벌크연산은 sql과 같이 update, delete 등의 절을 사용하면 된다. ( + execute())
주의사항
벌크연산은 영속성 컨텍스트에 캐시하지 않고 바로 DB에 적용시킨다. (@Modifying)
따라서 현재 영속성 컨텍스트에 저장된 값과 DB에 반영된 값에 차이가 생긴다.
해당 연산을 수행하고 곧바로 조회하면 영속성 컨텍스트에 캐싱된 데이터는 변경이 안된 데이터지만,
DB에는 변경된 데이터가 들어있다.
따라서 flush를 통해 DB와 맞추고
clear를 통해 영속성 컨텍스트를 초기화 해야한다.
'Spring > Querydsl' 카테고리의 다른 글
| Querydsl 기초 문법 2 (0) | 2022.07.25 |
|---|---|
| Querydsl 기초 문법 1 (0) | 2022.07.21 |
| Querydsl / 적용 (0) | 2022.07.21 |