본문 바로가기
JPA/스프링 DATA JPA

Data JPA 15 - Projections, 네이티브 쿼리

by 킹차니 2022. 1. 12.

Projections

 

- 엔티티 대신에 DTO를 편리하게 조회하고 싶을 때 사용 

- 전체 엔티티가 아니라 회원 이름만 조회하고 싶다면?

 

먼저 아래와 같이 인터페이스를 만들고, 조회할 엔티티의 필드를 getter형식으로 지정하면 해당 필드만 선택해서 조회(Projection)한다.

public interface UsernameOnly {
    String getUsername();//getter 형식으로 만든다.
}

 

그리고 리퍼지토리에서 아래와 같이 반환타입을 위에서 만든 인터페이스 타입으로 하면 된다.

public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom, JpaSpecificationExecutor<Member>{
	// 다른 메서드 생략 ..
    /* UsernameOnly 타입 */    
    List<UsernameOnly> findProjectionsByUsername(@Param("username") String username);
	
    // ...

}

이를 바로 사용하면 된다.

 

@Test
void projections() {
    //--given--
    Team teamA = new Team("teamA");
    em.persist(teamA);

    Member m1 = new Member("m1", 0, teamA);
    Member m2 = new Member("m2", 0, teamA);
    em.persist(m1);
    em.persist(m2);
    em.flush();
    em.clear();

    //--when--
    List<UsernameOnly> result = memberRepository.findProjectionsByUsername("m1");

    //--then--
    System.out.println(result.get(0));
}


실행결과:
org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap@198524ec

실행결과를 보면 Jpa가 프록시 객체를 만들어 반환해주는 것을 볼 수 있다.

 

실행된 쿼리를 보면 username만을 select하였다.

    select
        member0_.username as col_0_0_ 
    from
        member member0_ 
    where
        member0_.username=?

 

만약 일반적인 스프링 데이터 JPA로 아래와 같이 username으로 멤버를 찾는 쿼리를 만들고 위와 똑같은 테스트를 진행하면 아래와 같은 쿼리가 나가는데 말이다.

public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom, JpaSpecificationExecutor<Member>{

	// 다른 코드 생략 ...
    List<Member> findByUsername(@Param("username") String username);

	// projects 코드
    List<UsernameOnly> findProjectionsByUsername(@Param("username") String username);


}

findByUsername을 사용하고 같은 테스트를 했을 때 날라간 쿼리를 보면 member의 모든 정보 가져온다.

    select
        member0_.member_id as member_i1_1_,
        member0_.created_date as created_2_1_,
        member0_.last_modified_date as last_mod3_1_,
        member0_.created_by as created_4_1_,
        member0_.last_modified_by as last_mod5_1_,
        member0_.age as age6_1_,
        member0_.team_id as team_id8_1_,
        member0_.username as username7_1_ 
    from
        member member0_ 
    where
        member0_.username=?

 

 

 

 

 

 

김영한님의 인프런 강의와 PDF를 바탕으로 정리하였습니다.