요즘들어 회사업무가 많아서 개인공부할 시간이 많이 줄어들었다. 업무 중 내가 무심코 쓰던 용어들이 어느순간부터 구분이 안되고 있었고 글을 통해 정리해본다.
Client(Front-end)에서 Controller Layer로 데이터를 전송하고 그 데이터를 Service Layer로 전달한다. 여기서 사용되는 객체는 DTO이며, DAO에서 사용하는 객체는 Entity다.
Layer 간에 데이터 이동 객체로 getter/setter 외에 로직을 포함하지 않는다.
setter를 통해 변경가능하지만 Client에서 사용자가 보낸 데이터를 위/변조 하지 않기 위해서 setter 없이 사용할 수도 있다.
public class Money {
private int price;
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
값을 표현하기 위한 객체로써 불변객체이며 로직을 포함할 수 있다. 또한 equals, hashCode 등 override 하여 값이 같다면 같은 객체로 사용할 수 있다. 아래 코드를 살펴보자
public class Money {
private final int price;
public Money(final int price) {
this.price = price;
}
public int getHalfPrice() {
return price / 2;
}
@Override
public boolean equals(Object o) {
if(this == o) {
return true;
}
if (!(o instanceof Money)) {
return false;
}
Money money = (Money) o;
return price == money.price;
}
@Override
public int hashCode() {
return Objects.hash(price);
}
}
price 라는 필드 값을 가진 Money 라는 객체가 있다.
getHalfPrice 라는 로직이 들어갈 수 있으며 equals, hashCode 등 override 하여 값을 비교할 수도 있다.
Entity는 실제 DB 테이블과 매핑되는 객체이다. id로 구분되며 비즈니스 로직을 포함할 수 있고 DTO처럼 setter를 가지는 경우 가변 객체로 활용할 수 있다.
그렇다면 DTO를 대신 사용할 수 있는거 아닐까? 하는 의문을 가졌다. 하지만 요구사항에 따라 변하는 Front-end, Back-end 데이터 맞춰 DTO을 변경하다보면 테이블과 달라진다. 또한 민감정보를 노출할 수 없기에 Entity를 사용한다.
예를들어 User 라는 객체가 있다. 만약 저 User에서 변경email을 기존 email과 비교하는 로직이 들어간다면
beforeEmail, afterEmail이라는 값이 추가될것이다. 그렇다면 DB table에 값과 일치하지 않는다.
public class User {
private final Long id;
private final String email;
private final String password;
private final Integer age;
public User() {
}
public User(Long id, String email, String password, Integer age) {
this.id = id;
this.email = email;
this.password = password;
this.age = age;
}
}
DTO | VO | Entity | |
---|---|---|---|
개요 | 데이터 송/수신 객체 | 단순 값 표현 및 비교 객체 | DB Table과 매핑하는 객체 |
로직 포함 | X | O | O |
변경 가능 | O | X | X |
https://hyeon9mak.github.io/DTO-vs-VO/
https://www.youtube.com/watch?v=J_Dr6R0Ov8E
https://www.youtube.com/watch?v=4Pvd0KrTfvE