Published 2022. 7. 23. 16:50

가급적 네이티브 쿼리는 사용하지 않는게 좋음, 정말 어쩔 수 없을 때 사용
최근에 나온 궁극의 방법 스프링 데이터 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);}

 

 

JPQL은 위치 기반 파리미터를 1부터 시작하지만 네이티브 SQL은 0부터 시작
네이티브 SQL을 엔티티가 아닌 DTO로 변환은 하려면
DTO 대신 JPA TUPLE 조회
DTO 대신 MAP 조회
@SqlResultSetMapping 복잡
Hibernate ResultTransformer를 사용해야함 복잡
https://vladmihalcea.com/the-best-way-to-map-a-projection-query-to-a-dto-with-jpaand-hibernate/
네이티브 SQL을 DTO로 조회할 때는 JdbcTemplate or myBatis 권장

 

 

 

Projections 활용

예) 스프링 데이터 JPA 네이티브 쿼리 + 인터페이스 기반 Projections 활용

@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);

 

 

 

동적 네이티브 쿼리

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

 

 

예) 하이버네이트 기능 사용

//given
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 스프링 데이터 강의

'JPA > JPA-Spring Data' 카테고리의 다른 글

Projections  (0) 2022.07.23
새로운 엔티티를 구별하는 방법  (0) 2022.07.23
스프링 데이터 JPA 구현체 분석  (0) 2022.07.22
Web 확장 - 페이징과 정렬  (0) 2022.07.22
Web 확장 - 도메인 클래스 컨버터  (0) 2022.07.22
복사했습니다!