네이티브 쿼리

박찬우·2024년 1월 11일

스프링 데이터 JPA

목록 보기
18/18

네이티브 쿼리

  • 가급적 네이티브 쿼리는 사용하지 않는게 좋음, 정말 어쩔 수 없을 때 사용
  • 최근에 나온 궁극의 방법 스프링 데이터 Projections 활용
  • 페이징 지원
  • 반환 타입
    • Object[]
    • Tuple
    • DTO(스프링 데이터 인터페이스 Projections 지원)
  • 제약
    • Sort 파라미터를 통한 정렬이 정상 동작하지 않을 수 있음(믿지 말고 직접 처리)
    • JPQL처럼 애플리케이션 로딩 시점에 문법 확인 불가
    • 동적 쿼리 불가
@Query(value = "select * from member where username = ?", nativeQuery = true)
Member findByNativeQuery(String username);
Member result = memberRepository.findByNativeQuery("m1");
System.out.println(result);
  • JPQL은 위치 기반 파리미터를 1부터 시작하지만 네이티브 SQL은 0부터 시작
  • 네이티브 SQL을 엔티티가 아닌 DTO로 변환은 하려면
  • DTO 대신 JPA TUPLE 조회
  • DTO 대신 MAP 조회
  • @SqlResultSetMapping 복잡
  • Hibernate ResultTransformer를 사용해야함 복잡
  • 네이티브 SQL을 DTO로 조회할 때는 JdbcTemplate or myBatis 권장

Projections 활용

public interface MemberProjection {
    Long getId();
    String getUsername();
    String getTeamName();
}
@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> findByNativeProjections(Pageable pageable);
Page<MemberProjection> result = memberRepository.findByNativeProjections(PageRequest.of(0, 10));
List<MemberProjection> content = result.getContent();

for (MemberProjection memberProjection : content) {
	System.out.println(memberProjection.getId());
	System.out.println(memberProjection.getUsername());
	System.out.println(memberProjection.getTeamName());
}

동적 네이티브 쿼리

  • 하이버네이트를 직접 활용
  • 스프링 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();
}
profile
진짜 개발자가 되어보자

0개의 댓글