스프링데이터 + JPA/스프링 데이터 JPA

12. Dto나 테이블 중 특정 값만 조회해 오기

sdafdq 2023. 11. 20. 12:14

지금까지 그냥 엔티티 전체를 가지고 왔음.

 

이번엔 스프링 데이터 JPA로 Dto나 특정 값만 가져오는 걸 해 볼텐데,

 

이거는 메소드명으로 쿼리 자동생성으로는 못한다.

 

저 익명@Query를 써야 한다.

 

@Query("select m.username from Member m")
List<String> findUsernames();

그냥 우리가 순수 JPA에서 jpql 짜듯이 하면 된다.

 

 

그럼 다음은 Dto

@Data
public class MemberDto {
    private Long id;
    private String username;
    private String teamName;

    public MemberDto(Long id, String username, String teamName) {
        this.id = id;
        this.username = username;
        this.teamName = teamName;
    }
}
@Query("select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join m.team t")
List<MemberDto> findMemberDto();

이렇게 하면 된다.

이게 Jpa에서 Dto, 즉 엔티티가 아닌 다른 객체(임베디드 타입 제외)로써 받으면서 조회하고 싶을 때 늘 아쉬운 점이 저 new operation 이라고 해서 new 까지는 이해하겠는데,(new가 그 생성자 new 그거 얘기 하는 듯.)

패키지 명까지 모두 쓰는 건 아쉽다.

 

여튼 저런 식으로 생성자를 통해서 만들 수 있다.

 

@Test
public void testDto(){
    Member m1 = new Member("AAA", 10);
    Team team = new Team("teamA");
    m1.changeTeam(team);

    teamRepository.save(team);
    memberRepository.save(m1);

    List<MemberDto> result = memberRepository.findMemberDto();

    assertThat(result.get(0).getUsername()).isEqualTo(m1.getUsername());
    assertThat(result.get(0).getTeamName()).isEqualTo(m1.getTeam().getName());
    assertThat(result.get(0).getId()).isEqualTo(m1.getId());
}

member 생성한 다음, 팀 넣어주고,

team먼저 저장. 그래야 외래키를 가지고 있는 member쪽이 외래키 team_id를 저장할 수 있을테니.

 

그 다음 이제 한번 찾아와 봄.

찾아온 Dto랑 정의한 member랑 다 값이 똑같음.

 

이것도 쓰는 방법이긴 한 것 같고, 유용해보이긴 하는데,

QueryDSL쓰면 저 Dto 가져오는 것도 편해지는 듯.

편해진다기 보다는 클래스를 직접 지정하는거라서 패키지명을 안써도 된다고 했었나?