1. Native Query란?

Spring Data JPA에서는 기본적으로 JPQL(Java Persistence Query Language)을 사용하지만, 복잡한 SQL을 실행해야 할 경우 @Query 어노테이션을 활용하여 Native Query를 사용할 수 있습니다.

Native Query는 직접 SQL을 작성하여 실행하는 방식으로, 복잡한 조인, 성능 최적화, 데이터베이스 특정 기능을 사용할 때 유용합니다.


2. Native Query 사용법

(1) 기본적인 Native Query 사용

public interface MemberRepository extends JpaRepository<Member, Long> {
    
    @Query(value = "SELECT * FROM member WHERE username = :username", nativeQuery = true)
    Member findByUsername(@Param("username") String username);
}

위 코드에서는 nativeQuery = true를 설정하여 순수 SQL을 실행하고 있습니다.

(2) 여러 컬럼을 조회하는 경우

@Query(value = "SELECT id, username FROM member WHERE team_id = :teamId", nativeQuery = true)
List<Object[]> findMembersByTeamId(@Param("teamId") Long teamId);

위와 같이 List<Object[]> 형태로 데이터를 받을 수 있으며, 필요하면 DTO로 변환해야 합니다.

(3) DTO 매핑하여 조회하기

Native Query의 결과를 DTO로 매핑하려면 @SqlResultSetMapping 또는 Constructor Expression을 사용할 수 있습니다.

1) @SqlResultSetMapping 사용

@SqlResultSetMapping(
    name = "MemberDtoMapping",
    classes = @ConstructorResult(
        targetClass = MemberDto.class,
        columns = {
            @ColumnResult(name = "id", type = Long.class),
            @ColumnResult(name = "username", type = String.class)
        }
    )
)
@Query(value = "SELECT id, username FROM member WHERE team_id = :teamId", nativeQuery = true)
@SqlResultSetMapping("MemberDtoMapping")
List<MemberDto> findMemberDtoByTeamId(@Param("teamId") Long teamId);

2) Constructor Expression 사용

@Query(value = "SELECT new com.example.dto.MemberDto(m.id, m.username) FROM Member m WHERE m.team.id = :teamId")
List<MemberDto> findMemberDtoByTeamId(@Param("teamId") Long teamId);

3. Native Query 사용 시 주의점

(1) 데이터베이스 종속성

  • Native Query는 특정 데이터베이스의 SQL 문법을 따르므로, DBMS 변경 시 유지보수 비용이 증가할 수 있습니다.

(2) 결과 매핑 문제

  • Native Query는 자동으로 엔티티와 매핑되지 않기 때문에, 컬럼명을 정확하게 매칭하거나 DTO를 활용해야 합니다.

(3) 동적 쿼리 지원 부족

  • JPQL이나 QueryDSL과 달리, Native Query는 동적 쿼리 지원이 어렵기 때문에 String 기반으로 직접 조합해야 하는 불편함이 있습니다.
  • 이를 해결하기 위해 EntityManager.createNativeQuery() 또는 QueryDSL + SQL Templates를 활용할 수도 있습니다.

4. 결론

Spring Data JPA의 Native Query는 복잡한 SQL을 실행하거나, 성능 최적화가 필요할 때 유용하지만, 데이터베이스 종속성과 유지보수 비용이 높아질 수 있습니다. 따라서 가급적이면 JPQL, QueryDSL을 우선적으로 고려하고, 필요할 때만 Native Query를 활용하는 것이 좋습니다.

+ Recent posts