가급적 네이티브 쿼리는 사용하지 않는게 좋다. 정말 어쩔 수 없을 때 사용한다 

스프링 데이터 Projections를 활용한다 

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

1) 페이징 지원

2) 반환타입: Object[],Tuple,DTO(스프링 데이터 인터페이스 Projections 지원)

3) 제약:

sort 파라미터를 통한 정렬이 정상 동작하지 않을 수 있음(믿지 말고 직접 처리 하자)

JPQL처럼 애플리케이션 로딩 시점에 문법 확인 불가

동적 쿼리 불가 

 

2. JPA 네이티브 SQL 지원

public interface MemberRepository extends JpaRepository<Member, Long> {

      @Query(value = "select * from member where username = ?", nativeQuery = true)
      Member findByNativeQuery(String username);
 }

1) JPQL은 위치 기반 파라미터를 1부터 시작하지만, 네이티브 쿼리는 0부터 시작

2) 네이티브 쿼리를 엔티티가 아닌 DTO로 변환 하려면

DTO 대신 JPA TUPLE 조회

DTO 대신 MAP 조회

@SqlResultSetMapping -> 복잡

Hibernate ResultTransformer를 사용해야함 -> 복잡 

네이티브 쿼리를 DTO로 조회할 때는 JdbcTemplate or myBatis 권장

3. Projections 활용

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

closed인가?

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

 

4. 동적 네이티브 쿼리

하이버네이트를 직접 활용

스프링 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();
          
}

+ Recent posts