오봉이와 함께하는 개발 블로그

스프링 데이터 JPA - 네이티브 쿼리 본문

BE/JPA

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

오봉봉이 2022. 9. 14. 23:41
728x90

네이티브 쿼리

가급적 네이티브 쿼리는 사용하지 않는게 좋기 때문에 정말 어쩔 수 없을 때 사용하자.
최근에 나온 네이티브 쿼리 활용 방법은 스프링 데이터 Projections를 활용하는 방법이다.

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

  • 페이징 지원
  • 반환 타입
    • Object[]
    • Tuple
    • DTO(스프링 데이터 인터페이스 Projections를 지원함)
  • 제약
    • 반환 타입이 적기 때문에 사용하기 어중간하다.
    • Sort 파라미터를 통한 정렬이 정상 동작하지 않을 수 있음(믿지 말고 직접 처리)
    • JPQL처럼 애플리케이션 로딩 시점에 문법 확인 불가
    • 동적 쿼리 불가

JPA 네이티브 SQL 지원

public interface MemberRepository extends JpaRepository<Member, Long> {
    @Query(value = "select * from member where username = ?", nativeQuery = true)
    Member findByNativeQuery(String username);
}
select * from member where username = ?
select * from member where username = 'm1';

Projections 활용

스프링 데이터 JPA 네이티브 쿼리 + 인터페이스 기반 Projections 활용
네이티브 쿼리이기 때문에 페이징할 때 count쿼리를 꼭 짜야한다.

@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);
public interface MemberProjection {
    Long getId();
    String getUsername();
    String getTeamName();
}

동적 네이티브 쿼리

  • 하이버네이트 직접 활용
  • 스프링 JdbcTemplate, myBatis, jooq같은 외부 라이브러리 사용

하이버네이트 기능 사용

String sql = "select m.username as username from member m";
List<MemberDto> result = em.createNativeQuery(sql)
        .setFirstResult(0)
        .setMaxResults(10)
        .unwrap(NativeQuery.class)
        .addScalar("username")
        .setResultTransformer(Transformers.aliasToBean(MemberDto.class))
        .getResultList();
인프런 김영한 지식공유자님 강의 : 실전! 스프링 데이터 JPA
728x90
Comments