Entity 클래스는 실제 DB 테이블과 매핑되는 핵심 클래스로, 데이터 베이스의 테이블에 존재하는 컬럼들을 필드로 가지는 객체이다. DB의 테이블과 1:1로 매핑되며, 테이블이 가지지 않는 컬럼을 필드로 가져서는 안된다.
또한, Entity는 데이터 베이스와 연동되기 때문에 수정이 가능하며, Entity의 데이터가 변경되면 그 변경 사항이 데이터 베이스에 반영될 수 있다.
Entity는 데이터 베이스 영속성 (persistent)의 목적으로 사용되는 객체이기 때문에 요청(Request) 나 응답(Response) 값을 전달하는 클래스로 사용하는 것은 좋지 않다.
또, 많은 서비스 클래스와 비즈니스 로직들이 Entity 클래스를 기준으로 동작하기 때문에 Entity 클래스가 변경되면 여러 클래스에 영향을 줄 수 있다.
주로 JPA나 Hibernate 같은 ORM(Object-Relational Mapping) 프레임워크에서 사용한다.
Entity에서는 setter 메서드의 사용을 지양해야한다. 왜냐하면, 변경되지 않는 인스턴스에 대해서도 setter로 접근이 가능해지기 때문에 객체의 일관성, 안전성을 보장하기 힘들어지기 때문이다.
setter 메서드가 아닌 생성자(Constructor)를 이용해서 초기화하는 경우 불변 객체로 활용할 수 있고, 불변 객체로 만들면 데이터를전달하는 과정에서 데이터가 변조되지않음을 보장할 수 있다.
아래 코드처럼 Builder를 사용하여 멤버 변수가 많아지더라도 어떤 값을 어떤 필드에 넣는지 코드를 통해 확인할 수 있고, 필요한 값만 넣는 것이 가능하다는 장점이 있다.
import javax.persistence.*;
import lombok.*;
@Entity
@Table(name = "sangdata")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SangpumEntity {
@Id
@Column(name = "code")
private int code;
@Column(nullable = false)
private String sang;
private int su;
private int dan;
}
DTO (Data Transfer Object)
DTO는계층(Layer) 간 데이터 교환이 이루어질 수 있도록 하는 객체로 JSON serialization과 같은 직렬화에도 사용되는 객체이다.
DTO는 원래 DAO(Data Access Object) 패턴에서 유래된 단어로 DAO에서 DB처리 로직을 숨기고 DTO라는 결괏값을 내보내는 용도로 활용했다.
Controller 같은 클라이어언트 단과 직접 마주하는 계층에서는 Entity 대신 DTO를 사용해서 데이터를 교환하며, Controller외에도 여러 레이어 사이에서 DTO를 사용할 수 있지만 주로 View와 Controller 사이에서 데이터를 주고받을 때 활용성이 높다.
DTO는 getter, setter 메서드를 포함하며, 이 외의 비즈니스 로직은 포함하지 않는다.
데이터 베이스와 직접적인 연관이 없으며 필요한 필드만 포함할 수 있다.
package pack.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BuserDto { //데이터 전달용
//DTO는 엔티티에서 필요한 데이터만 추출하거나, 전체 데이터를 읽어 또 다른 클래스, 클라이언트에 전달
private int buserno;
private String busername;
private String buserloc;
private String busertel;
//Buser(Entity)를 BuserDto로 변환
/* 빌더 패턴 안씀
public static BuserDto fromEntity(Buser entity) {
BuserDto dto = new BuserDto();
dto.setBuserno(entity.getBuserno());
dto.setBusername(entity.getBusername());
dto.setBuserloc(entity.getBuserloc());
dto.setBusertel(entity.getBusertel());
return dto;
}
*/
//빌더 패턴 쓴 ver
public static BuserDto fromEntity(Buser entity) {
return BuserDto.builder()
.buserno(entity.getBuserno())
.busername(entity.getBusername())
.buserloc(entity.getBuserloc())
.busertel(entity.getBusertel())
.build();
}
}
Entity와 DTO 차이점 요약
구분
Entity
DTO
목적
데이터 베이스와의 직접적인 연동
계층 간 데이터 전달
영속성
데이터 베이스 테이블과 매핑 (영속성 있음)
영속성이 없고 데이터 전송에만 집중
변경 가능성
업데이트 가능
주로 불변 객체로 사용
비즈니스 로직
간단한 비즈니스 로직 포함 가능
비즈니스 로직 없음
사용 위치
주로 서비스 및 데이터 베이스 레이어
컨트롤러와 서비스 레이어 간 데이터 전달
역할 분리를 위한 Entity와 DTO 작성의 이유
유지보수성 : Entity는 데이터 베이스와 직접적으로 매핑되는 클래스이다. 따라서 데이터 베이스 스키마와 일치해야하므로 변경에 민감할 수 있다. 반면, DTO는 계층 간 데이터 전달을 위한 객체로, 주로 비즈니스 로직과 프레젠테이션 계층에서 사용된다.
보안 : Entity에는 데이터 베이스 구조가 포함되어 있다. 이를 외부에 직접 노출하면 보안상 위험할 수 있다. DTO를 사용하면 필요한 데이터만 선택적으로 전달할 수 있어 보안을 강화할 수 있다.
성능 : Entity 객체는 종종 불필요한 데이터까지 포함하고 있는 경우가 많다. DTO는 필요한 데이터만 포함하여 전송할 수 있기 때문에 네트워크 성능을 향상 시킬 수 있다.
유연성 : Entity와 DTO를 분리하면, 데이터 베이스 스키마가 변경되더라도 DTO 구조는 독립적으로 유지할 수 있다. 이로 인해 데이터 베이스를 리팩토링할 때 애플리케이션 로직을 변경하지 않아도 된다.