오늘의 인기 글
최근 글
최근 댓글
Today
Total
02-02 00:01
관리 메뉴

우노

[Kotlin] @SqlResultSetMapping 본문

Web_App/Kotlin

[Kotlin] @SqlResultSetMapping

운호(Noah) 2024. 12. 20. 10:12

@SqlResultSetMapping

  • @SqlResultSetMapping은 네이티브 쿼리의 결과를 JPA에서 사용할 수 있는 형식으로 매핑하기 위해 사용하는 어노테이션입니다.
  • 쉽게 말하면, 데이터베이스에서 가져온 데이터를 Entity나 DTO로 변환해주는 설계도라고 보면 됩니다.

왜 필요한가요?

  • 기본적으로 JPA는 쿼리 결과를 자동으로 매핑해 주지만,
  • 복잡한 쿼리나 특정 구조의 데이터를 반환해야 할 경우 직접 매핑을 설정해야 합니다.
  • @SqlResultSetMapping을 사용하면 이런 매핑 과정을 명확하고 간단하게 정의할 수 있습니다.

어떻게 사용하나요?

  • 데이터베이스의 결과를 Entity로 매핑 (EntityResult)

    • 사용 예시

        @SqlResultSetMapping(
            name = "UserMapping", // 매핑 이름
            entities = @EntityResult( // 엔티티로 매핑
                entityClass = User.class, // 어떤 엔티티에 매핑할지 지정
                fields = { // 쿼리 결과 컬럼 -> 엔티티 필드 매핑
                    @FieldResult(name = "id", column = "user_id"),
                    @FieldResult(name = "username", column = "user_name"),
                    @FieldResult(name = "email", column = "user_email")
                }
            )
        )
      
        // User 엔티티 정의
        @Entity
        public class User { 
            @Id
            private Long id;
            private String username;
            private String email;
        }
      
    • 쿼리 사용

        @Query(value = "SELECT user_id, user_name, user_email FROM users", nativeQuery = true)
        @SqlResultSetMapping(name = "UserMapping") // 매핑 참조
        List<User> findUsers();
    • 결과

      • 데이터베이스에서 가져온 쿼리 결과가 User Entity 객체에 자동으로 매핑됩니다.
      • 예를 들어, user_id → id, user_name → username과 같이 컬럼 이름이 엔티티 필드에 대응됩니다.
  • 데이터베이스의 결과를 DTO로 매핑 (ConstructorResult)

    • Entity가 아닌 DTO 또는 별도의 클래스로 데이터를 매핑할 때 사용합니다.

    • 이 경우 생성자를 통해 데이터를 전달합니다.

    • 사용 예시

        @SqlResultSetMapping(
            name = "UserDTOConstructorMapping", // 매핑 이름
            classes = @ConstructorResult( // 생성자를 통해 매핑
                targetClass = UserDTO.class, // 어떤 클래스에 매핑할지 지정
                columns = { // 쿼리 결과 컬럼 -> 생성자 매개변수 매핑
                    @ColumnResult(name = "user_id", type = Long.class),
                    @ColumnResult(name = "user_name", type = String.class),
                    @ColumnResult(name = "user_email", type = String.class)
                }
            )
        )
      
        // DTO 클래스 정의
        public class UserDTO {
            private Long id;
            private String username;
            private String email;
      
            public UserDTO(Long id, String username, String email) { // 생성자
                this.id = id;
                this.username = username;
                this.email = email;
            }
        }
    • 쿼리 사용

        @Query(value = "SELECT user_id, user_name, user_email FROM users", nativeQuery = true)
        @SqlResultSetMapping(name = "UserDTOConstructorMapping") // 매핑 참조
        List<UserDTO> findUserDTOs();
    • 결과

      • 쿼리 결과가 UserDTO 객체에 매핑됩니다.
      • 예를 들어, user_id → 생성자의 id, user_name → username 매개변수로 전달됩니다.

요약

  • EntityResult : 데이터베이스 결과를 Entity로 매핑
  • ConstructorResult : 데이터베이스 결과를 DTO로 매핑

장점

  • 유연성: 복잡한 쿼리 결과를 Entity나 DTO에 매핑 가능
  • 재사용성: 동일한 매핑 이름을 여러 네이티브 쿼리에서 재사용 가능
  • 가독성: 매핑 규칙이 명확히 정의되어 코드 가독성 향상

단점

  • 유지 보수 어려움: 컬럼 이름 변경 시 매핑 설정도 함께 수정 필요
  • DB 의존성 증가: 네이티브 쿼리 사용으로 특정 DB 종속 가능성

사용 시점

  • 여러 테이블 조합: 엔티티로 표현하기 어려운 데이터를 반환해야 할 때
  • DTO 반환: 엔티티 외부 데이터를 가공해 API 응답으로 전달해야 할 때

'Web_App > Kotlin' 카테고리의 다른 글

[Kotlin] @Service vs @Component  (2) 2024.12.23
[Kotlin] Controller와 Service의 계층 구조  (0) 2024.12.20
[Kotlin] ORM, JPA, Spring Data JPA  (1) 2024.12.18
[Kotlin] @Entity와 @Repository  (0) 2024.12.18
[Kotlin] DTO와 Entity의 관계  (0) 2024.12.17
Comments