개요
- 데이터베이스에서 조회(SELECT) 하는 3가지의 방법
- 설렉션(Selection) - 행 단위로 원하는 데이터를 조회하는 방식
- 프로젝션(Projection) - 열 단위로 원하는 데이터를 조회하는 방식
- 조인(Join) - 두 개 이상의 테이블을 양옆에 연결하여 데이터를 조회하는 방식
- 즉, 프로젝션은 SELECT 를 통해 조회할 대상을 지정하는 것을 뜻한다.
- 프로젝션 결과를 DTO 로 직접 조회 해보자.
- 엔티티를 조회하여 DTO로 변환하지 않고, 리포지토리에서 DTO를 이용하여 바로 조회한다.
- 리포지토리 재사용성이 떨어짐, API 스펙에 맞춘 코드가 리포지토리에 들어가는 단점이다.
- 리포지토리는 가급적 순수한 엔티티를 조회하는데 사용하기 때문에 따로 DTO로 조회하여야 한다면 리포지토리를 만드는 것이 유지보수성에 좋다.
- 대량의 데이터 조회가 필요하거나 성능 최적화를 고강도로 하고 싶은 경우 DTO 조회
- 비즈니스 로직에서 실시간으로 엔티티 변경이 필요한 경우 Entity 조회
- DTO 에서 정의하는 필드와 Repository 에서 SELECT 으로 표현하고자 하는 필드가 완전히 일치해야 한다.
순수 JPA 에서 DTO 조회
@Data
public class MemberDto {
private String userName;
private int age;
public MemberDto() {
}
public MemberDto(String userName, int age) {
this.userName = userName;
this.age = age;
}
}
@Test
void findDtoByJPQL() {
//given
//when
String qlString = "select new study.querydsl.dto.MemberDto(m.userName, m.age) from Member m";
List<MemberDto> result = em.createQuery(qlString, MemberDto.class)
.getResultList();
//then
for (MemberDto memberDto : result) {
System.out.println("memberDto = " + memberDto);
}
}
- 순수 JPA 에서 DTO 를 조회할 때는 new 명령어를 사용해야 한다.
- DTO 의 Package Name 도 모두 적어줘야 해서 가독성이 많이 떨어진다.
- 생성자 방식만 지원한다.
Querydsl 빈 생성(Bean pipulation)
- Querydsl 을 사용하면 3가지의 방법으로 결과를 DTO 로 변환할 수 있다.
- 프로퍼티(Setter) 접근
- 필드(Field) 직접 접근
- 생성자(Constructor) 사용
프로퍼티(Setter) 접근
@Test
void findDtoBySetter() {
//given
//when
List<MemberDto> result = jpaQueryFactory
.select(Projections.bean(MemberDto.class,
member.userName,
member.age))
.from(member)
.fetch();
//then
for (MemberDto memberDto : result) {
System.out.println("memberDto = " + memberDto);
}
}