Spring Data JPA - 네이티브 쿼리

2022. 8. 3. 22:01·공부/JPA
반응형

출처 : 인프런 실전! 스프링 데이터 JPA

Spring Data JPA 게시글은 대부분 인프런의 김영한님의 강의인 '실전! 스프링 데이터 JPA' 기반으로 내용을 정리했습니다.

 

네이티브 쿼리

네이티브 쿼리는 JPA에서 제공하는 기능이며 일반적으로 우리가 사용하는 SQL을 사용할 수 있도록 해주는 기능이다. 가급적 네이티브 쿼리는 사용하지 않는 것이 좋다. 정말 최후의 수단으로.. 어쩔 수 없는 상황에만 사용하는 걸 권장한다. 

 

 

스프링 데이터 JPA 기반 네이티브 쿼리

  • MemberRepository.interface
@Query(value = "select * from member where username = ?", nativeQuery = true)
Member findByNativeQuery(String username);
  • MemberRepositoryTest.class
@Test
public void nativeQuery() {
    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();

    Member result = memberRepository.findByNativeQuery("m1");
    System.out.println("result = " + result);
}
    select
        * 
    from
        member 
    where
        username = ?
result = Member(id=2, username=m1, age=0)

이렇게 사용하면 되는 기능이다. 근데 이 기능은 제약이 되게 많다. 일단 엔티티의 한 컬럼의 데이터만 가져오려면 반환 타입을 변경해야 하는데 반환 타입으로 지정할 수 있는 게 너무 한정적이다. 그리고 뭔가 네이티브 쿼리를 사용해서 데이터를 가져오는 행위 자체가 단순한 조회 목적이라기 보다는 엄청 대용량의 데이터를 join 하거나 할 때 쓰는 등의 제약이 있다.

정리하자면

  • 반환 타입
    • Object[]
    • Tuple
    • DTO(원래는 안됐었지만 최근에 업데이트 됨)
  • 제약
    • Sort 파라미터를 통한 정렬이 정상적으로 동작하지 않을 수 있다.(직접 처리해야 함. 어쩔땐 되고, 어쩔땐 안 된다.)
    • JPQL처럼 애플리케이션 로딩 시점에 문법 확인이 불가능하다.
    • 동적 쿼리가 불가능하다.
  • 네이티브 SQL을 DTO로 조회할 때는 JdbcTemplate이나 myBatis를 사용하는 걸 권장한다.

 

 

Projections 활용

그래도 Projections를 활용하면 더 쉽게 사용할 수 있다. 단 동적 쿼리는 사용하기 쉽지 않다.

  • MemberProjection.interface
public interface MemberProjection {

    Long getId();
    String getUsername();
    String getTeamName();
}
  • MemberRepository.interface
@Query(value = "select m.member_id as id, 
	m.username, t.name as teamName from Member m " +
        "left join team, t",
        countQuery = "select count(*) from member",
        nativeQuery = true)
Page<MemberProjection>findByNativeProjection(Pageable pageable);

JPA가 아니라서 count 쿼리를 직접 만들어줘야 한다.

  • MemberRepositoryTest.class
Page<MemberProjection> result = memberRepository
		.findByNativeProjection(PageRequest.of(0, 10));
List<MemberProjection> content = result.getContent();
for (MemberProjection memberProjection : content) {
    System.out.println("memberProjection = " + memberProjection.getUsername());
    System.out.println("memberProjection = " + memberProjection.getTeamName());
}
select
    m.member_id as id,
    m.username,
    t.name as teamName 
from
    Member m 
left join
    team t limit ? offset ?


select
	count(*) 
	from
member
    
    
memberProjection = m1
memberProjection = teamA
memberProjection = m2
memberProjection = teamA

 

반응형
저작자표시 비영리 변경금지 (새창열림)
'공부/JPA' 카테고리의 다른 글
  • Query DSL - Query DSL 설정과 검증
  • Query DSL - 프로젝트 환경설정
  • Spring Data JPA - Projections
  • Spring Data JPA - Query By Example
데부한
데부한
어차피 할 거면 긍정적으로 하고 싶은 개발자
    반응형
  • 데부한
    동동이개발바닥
    데부한
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • 방통대 컴퓨터과학과 (27)
        • 잡담 (9)
        • 3학년1학기 (17)
      • 프로젝트 및 컨퍼런스 회고 (1)
        • 프로젝트 (4)
        • 한이음 프로젝트 (0)
        • 회고 (3)
      • 공부 (165)
        • Spring (37)
        • JPA (71)
        • 인프런 워밍업 클럽_BE (10)
        • Java (6)
        • React.js (27)
        • 넥사크로 (11)
        • 기타 (3)
      • 알고리즘 (85)
        • 알고리즘 유형 (10)
        • 알고리즘 풀이 (57)
        • SQL 풀이 (18)
      • 에러 해결 (13)
      • 잡담 (7)
        • 국비교육 (2)
        • 구매후기 (5)
        • 진짜 잡담 (0)
  • 블로그 메뉴

    • Github
    • Linkedin
    • 홈
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    egov
    토비의스프링부트
    oracle
    운영체제
    QueryDSL
    에러해결
    SpringBoot를 이용한 RESTful Web Service 개발
    기출문제
    Java
    react
    개발자
    JPA
    토이프로젝트
    MSA
    넥사크로
    알고리즘
    IT
    프론트엔드
    springboot
    인프런
    자바스크립트
    방통대
    스프링부트
    Spring
    RESTful
    백준
    SQL
    프로그래머스
    전자정부프레임워크
    코딩테스트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
데부한
Spring Data JPA - 네이티브 쿼리
상단으로

티스토리툴바