네이티브 쿼리란? JPA 표준 JPQL 대신 데이터베이스 고유의 SQL 쿼리를 사용하여 엔티티를 조회하는 기능 가급적이면 사용하지 않는 게 좋다. 정말 어쩔 수 없는 경우에만 사용해야 한다. 특징 JPQL 제약 극복JPQL로 표현하기 어려운 복잡한 쿼리를 작성할 수 있습니다. 데이터베이스 최적화데이터베이스 특화 기능을 활용하여 쿼리 성능을 향상시킬 수 있습니다. 유연성 문제점 Sort 파라미터를 통한 정렬이 정상 동작하지 않을 수 있다. JPQL처럼 애플리케이션 로딩 시점에 문법 확인할 수 없다. 동적 쿼리가 불가능하다.하이버네이트를 직접 활용하면 가능은 하다. 그냥 JdbcTemplate 또는 myBatis를 사용하는 것이 좋다. 사용 방법 리포지토리에 네이티브 쿼리를 사용할 메소드를 생성한다. public interface MemberRepository extends JpaRepository < Member , Long > {
Member findByNativeQuery ( String username );
}
1번에서 생성한 메소드에 @Query
어노테이션을 추가하고, 쿼리를 작성한 뒤, nativeQuery = true
속성을 명시한다. public interface MemberRepository extends JpaRepository < Member , Long > {
@Query ( value = "select * from member where username = ?" , nativeQuery = true )
Member findByNativeQuery ( String username );
}
필요한 곳에서 사용한다. @Test
public void nativeQuery () {
//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
Member result = memberRepository . findByNativeQuery ( "m1" );
System . out . println ( "result = " + result );
}
@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 );
@Test
public void nativeQuery () {
//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
Page < MemberProjection > result = memberRepository . findByNativeProjection ( PageRequest . of ( 0 , 10 ));
List < MemberProjection > content = result . getContent ();
for ( MemberProjection memberProjection : content ) {
System . out . println ( "memberProjection = " + memberProjection . getUsername () + " / " + memberProjection . getTeamName ());
}
}
주의 사항 JPQL은 위치 기반 파리미터를 1부터 시작하지만 네이티브 쿼리는 0부터 시작한다. 네이티브 쿼리로 엔티티가 아닌 DTO로 조회하기는 JdbcTemplate 또는 myBatis를 사용하는 것이 좋다. 네이티브 쿼리는 데이터베이스 플랫폼에 종속적이기 때문에, 플랫폼이 변경되면 쿼리를 수정해야 된다. JPQL보다 더 복잡하고 오류 가능성이 높다. DTO 대신에 프로젝션으로 조회할 수 있다. 출처