본문 바로가기
자바/Spring

DTO와 Entity

by 공부하는 스프링 개발자 2023. 5. 16.
반응형

오늘은 Spring MVC에서 사용되는 Entity와 DTO에 대해서 말해보려고 합니다. 먼저 Entity에 대해서 설명하고, 다음은 DTO에 대해서 설명하겠습니다. 그리고 Entity와 DTO를 어떤 식으로 변환하는지도 코드로 간단하게 알아보도록 하겠습니다.

 

Entity

Entity는 데이터베이스 테이블과 매핑되는 객체입니다. 보통 객체 지향 프로그래밍에서 엔티티는 특정 도메인 또는 개념을 나타내는 클래스입니다. 데이터베이스의 테이블과 매핑되기 때문에 엔티티는 데이터베이스의 테이블 구조와 일치하는 필드를 가지고 있습니다.

 

즉, Entity는 데이터베이스와 직접 맞닿아 있다는 것을 의미하고, 그렇기 때문에 컨트롤러나 VIew에 직접 전달하여 사용하는 것은 권장되지 않습니다. 그 이유는 컨트롤러나 View로 접근해야 하는 경우에는 속성을 변경해야 하는 경우가 생길 수 있기 때문입니다. 또, 같은 이유로 Entity에는 Setter를 두지 않는 것이 권장됩니다. 대신, 컨트롤러나 View에 접근해야 하는 경우 Entity 객체를 직접 직접 전달하는 대신 데이터 전송 객체(Data Transfer Object, DTO)를 사용하는 것이 좋습니다.

 

DTO

DTO는 Data Transfer Object의 약자로, 터베이스와의 상호작용을 하지 않고, 데이터의 전송만을 목적으로하는 객체입니다. 즉, DTO는 계층 간 데이터 교환을 위해서만 사용됩니다.

 

그렇다면 Entity 객체를 DTO 객체로 변환하는 일은 어디에서 처리하는 것이 좋을까요? 다양한 의견이 있겠지만, 제 생각에는 서비스 레이어에서 변경하는 것이 좋다고 생각합니다. 제가 이렇게 생각하는 근거는 역할과 책임 분리, 계층간 의존성 분리입니다.

 

역할과 책임 분리

서비스 계층은 비즈니스 로직을 처리하고, 컨트롤러는 클라이언트와 상호작용, HTTP 요청 처리를 담당합니다. 서비스 계층에서 분리를 하면 데이터의 가공과 비즈니스 로직에 집중할 수 있기에 역할과 책임을 분리한다고 할 수 있습니다. 

 

이게 무슨 말이냐면, 비즈니스 로직은 데이터를 가공하고 조작하여 필요한 형태로 변환하는 작업인데, DTO를 Entity로, Entity를 DTO로 변환하는 것은 데이터를 서비스 계층에서 필요한 형식으로 가공하는 것이라고 생각할 수 있습니다.

 

계층 간 의존성 분리

Entity를 컨트롤러에서 변환하면 컨트롤러와 Entity 간의 의존성이 강해집니다. 하지만 서비스계층에서 변환하면 컨트롤러는 Entity의 변환 없이 서비스를 호출할 수 있습니다.

 

 

Entity-to-DTO
Entity to DTO

주저리주저리 말이 많았는데, 결론적으로는 위의 사진처럼 이루어진다고 생각하시면 됩니다. 그림판으로 그렸는데, 생각보다 시간이 오래 걸렸네요..

 

클라이언트에서 컨트롤러로, 컨트롤러에서 서비스로 보낼 때는 DTO를 사용하고, 서비스 레이어에서 Entity로 변환한 후 Repository(DAO라고도 함)로 보내고, Repository(DAO)에서 DB에 접근합니다. 물론 Entity를 DTO로 변환할 때는 반대의 과정을 거칩니다. 이런 식으로 서비스 레이어에서 Entity를 DTO로 변경해 컨트롤러로 보내면 Entity 클래스에서 사용되는 속성을 보호할 수 있어 엔티티 클래스를 직접 사용하는 것보다 더 안전하게 DB에 접근할 수 있습니다.

그런데 위에서 Entity에는 Setter를 만들지 않는다고 했습니다. 그렇다면 어떻게 데이터의 변경을 넣어주어야 할까요? 저는 빌더 패턴으로 해답을 찾았습니다.

 

import lombok.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DTO{

    private Integer ex1;
    private String ex2;

    public ExEntity toEntity(){
        return AnswerEntity.builder()
                .ex1(ex1)
                .ex2(ex2)
                .build();
    }
}

위는 DTO이고, 아래는 Entity입니다.

import lombok.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DTO{

    private Integer ex1;
    private String ex2;

    public ExEntity toEntity(){
        return AnswerEntity.builder()
                .ex1(ex1)
                .ex2(ex2)
                .build();
    }
}

이런 식으로 빌더패턴을 이용해서 toEntity와 toDTO라는 메서드를 만들어주면 Setter가 없이도 DTO를 Entity로 변환할 수 있습니다. 참고로 롬복의 @Builder를 @NoArgsConstructor와 함께 사용하려면 @AllArgsConstructior를 함께 사용하거나, 모든 필드를 가진 생성자를 직접 만들어 주어야 합니다.

반응형

'자바 > Spring' 카테고리의 다른 글

서블릿(Servlet) 컨테이너에 대해서  (0) 2022.10.30

댓글