JPA를 사용할 때 DTO(Data Transfer Object)를 어떻게 정의할지 고민이 되는 경우가 많습니다. 특히 interface
기반 DTO와 class
기반 DTO 중 어떤 방식을 선택해야 할지 혼란스러울 수 있는데요, 이번 글에서는 두 방식의 차이점과 사용 목적에 따라 어떤 방식을 선택하면 좋을지 정리해보았습니다.
Interface 기반 DTO
예시
public interface UserDto {
String getName();
int getAge();
}
@Query("SELECT u.name as name, u.age as age FROM User u")
List<UserDto> findUsers();
장점
- 코드가 간단하며, getter만 정의하면 JPA가 구현체를 자동으로 생성합니다.
- 읽기 전용 DTO에 적합합니다.
- 추가적인 클래스를 정의하지 않아도 되어 빠르게 개발할 수 있습니다.
단점
- getter만 지원되며, 로직을 포함할 수 없습니다.
- 구조 변경이나 커스터마이징에 제약이 많습니다.
- 필드명이 쿼리와 정확히 일치해야 하므로 유연성이 떨어집니다.
Class 기반 DTO
예시
public class UserDto {
private String name;
private int age;
public UserDto(String name, int age) {
this.name = name;
this.age = age;
}
// getter, setter
}
@Query("SELECT new com.example.dto.UserDto(u.name, u.age) FROM User u")
List<UserDto> findUsers();
장점
- 생성자, 메서드, 유효성 검사 등 자유로운 커스터마이징이 가능합니다.
- 복잡한 데이터 변환이나 후처리가 필요한 경우에 유용합니다.
- 일반적인 Java 객체처럼 다룰 수 있어 유연성이 높습니다.
단점
new
키워드를 활용한 객체 생성이 필요해 쿼리가 다소 복잡해질 수 있습니다.- 생성자 매개변수의 순서와 타입을 정확히 맞춰야 합니다.
어떤 방식을 선택할까?
상황 | 권장 방식 |
---|---|
단순한 조회 쿼리 | Interface |
계산, 파싱, 후처리 등 로직 필요 | Class |
DTO에 포맷팅, 유효성 검사 등 추가 작업이 필요한 경우 | Class |
빠르게 읽기용 결과만 보고 싶을 때 | Interface |
마무리
결론적으로 JPA에서 DTO를 구현할 때 interface와 class는 각각의 목적에 따라 선택하는 것이 가장 좋습니다. 단순한 조회만 필요할 때는 interface가 효율적이며, 로직이 필요하거나 유연성이 중요한 경우에는 class 방식이 더 적합합니다. 상황에 따라 두 방식을 병행해 사용하는 것도 좋은 전략이 될 수 있습니다.
반응형
'개발 (Development) > Java' 카테고리의 다른 글
[Java] Interface란? 클래스와 다른 점은? (0) | 2025.08.03 |
---|---|
[Java] MyBatis와 JPA 속도 비교: 어떤 상황에 어떤 선택이 더 나을까? (0) | 2025.08.03 |
[Java] MyBatis만 쓰던 내가 JPA를 처음 접했을 때 이해한 구조 정리 (0) | 2025.08.03 |
[Java] Spring Boot 프로젝트에서 MyBatis와 JPA를 함께 사용하는 방법과 오류 해결 과정 (0) | 2025.08.03 |
[Java] Spring Boot 2.x + Java 11 환경에서 JPA Native Query와 DTO 매핑 문제 해결 기록 (4) | 2025.08.03 |