무엇을 줄이는가 엔티티를 조회하면 매핑된 모든 칼럼이 SELECT 에 들어간다. 화면에 이름과 나이만 쓰는데도 본문·이미지 경로까지 읽어 오면, 낭비는 세 곳에서 동시에 생긴다 — 디스크에서 읽는 데이터 페이지 양, 네트워크로 오가는 바이트, 그리고 JVM 힙에 만들어지는 객체 크기. 프로젝션은 SELECT 목록 자체를 줄여 이 셋을 함께 줄인다.
QueryDSL 에서의 세 가지 형태
| 방식 | 매핑 기준 | 조건 |
|---|---|---|
Projections.constructor | 생성자 파라미터 순서 | 순서가 어긋나면 런타임에 잘못 매핑 |
Projections.fields | 필드 이름 | 이름이 다르면 as() 로 별칭 필요 |
Projections.bean | setter 이름 | 기본 생성자와 setter 필요 |
query.select(Projections.constructor(MemberDto.class, member.email, member.age))
.from(member)
.fetch();
엔티티를 꺼내 변환하는 것과 무엇이 다른가 엔티티로 받아 서비스에서 DTO 로 바꾸면 쿼리는 이미 전체 칼럼을 읽은 뒤다. 게다가 조회한 엔티티는 영속성 컨텍스트 가 관리 대상으로 붙잡아 스냅샷까지 떠 두므로, 읽기 전용 목록 조회에서는 순전히 비용만 남는다. 프로젝션으로 받은 DTO 는 관리 대상이 아니라 변경 감지도, 스냅샷도 없다.
주의 프로젝션 결과는 영속 상태가 아니므로 값을 바꿔도 DB 에 반영되지 않는다. 이는 결함이 아니라 읽기 전용이라는 의도다. 수정이 필요한 흐름에서는 엔티티로 조회해야 한다.