한번 쯤 들어보았을 DTO, DAO, Entity, Service.
이 4개는 무엇이고 왜 쓰는걸까?
이는 내가 못찾은건지 인터넷에 없는건지 정말 모르겠었다.
그래서 내가 직접 사용하며 느꼇던 점을 정리해보기로 했다.
내가 느꼇던점은 이것들인데 정확한지는 잘 모르겠다.
DTO는 Data Transfer Object의 약어로, 계층간 데이터 교환을 위해 사용하는 자바 객체이다.
이는 Entity 와 매우 흡사한 구조를 가지고 있는데 왜 따로 선언을 해야할까?
이 부분은 DTO / Entity를 정리하며 대강 이해만 해보자
DTO는 Client와 직접적으로 통신을 할 때 이용되는 개념이다.
통신을 할 때는 Request와 Response로 나뉘기때문에 RequsetDTO 와 ResponseDTO로 나뉘게 된다.
굳이 이렇게나누나? 라는 생각이 있지만, 로그인을 예시로 들어보자.
로그인을 할 때 id와 pw를 GET Parameter로 보낸다고 해보자.
그렇다면, http://localhost:8080/api/users?id=test&pw=test1234!!
이런 형태로 GET요청을 보내게 된다.
자, 그럼 여기에 해당하는 DTO는 어떻게 될까?
public class LoginDTO{
private String id;
private String pw;
}
이런식으로 될것이다. 그런데, 로그인을 할 때 우리가 받아오는 정보를 정리해보면
이메일, 아이디, 닉네임, 성별, 나이
등등 다양한 정보를 받아오는데, 위에 보면 Login 할 때 id와 pw만 받는다.
public class LoginDTO{
public static class Requset{
private String id;
private String pw;
}
public static class Response{
private int no;
private String email;
private String id;
private String nickName;
...
}
}
이런식으로 InnerClass를 이용해서 정리를 할 수 있다.
꼭 InnerClass로 해야하는것은 아니지만, 필자는 이런 방법을 선호하고있다.
이는 개발자의 취향차이 혹은, 팀의 선택사항이라고 할 수 잇을것이다.
자, 그럼 DTO는 Client와 직접적으로 통신을 한다고 했다.
그렇다면 통신을 제외한 다른 비즈니스로직이 존재해도 될까? 답은 아니다.
DTO는 통신을 위한 순수 데이터객체이기때문에 비즈니스 로직이 존재해서는 안되는 객체이다
위에 언급했듯이 Entity는 DTO와 상당히 유사한 구조를 지닌다.
구조가 어떻길래 유사한가? Auth라는 Entity가 있다는 가정하에 코드를 작성해보겠다.
@Entity
@Builder
@Table(name="auth")
public class AuthEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int no;
private String id;
private String pw;
private String email;
private String nickname;
.....
}
이런 형태의 Entity가 생성된다.
위에 언급했듯이 유사한 형태가 나타나게 되는데, 차이점은 Entity 클래스는 DB와 직접 매핑이 된다는것이다.
이게 무슨소리냐면, Entity클래스는 DB테이블 안에 존재하는 컬럼의 이름과 데이터 형식에 매핑되는 클래스다. 이 Entity클래스를 사용할 때 약간의 설정을 추가해준다면 DB스키마가 자동으로 생성/수정 되는것을 확인할 수 있다.
이는 DB를 직접 조회하고 이를 활용할 때 사용하는 객체이다.
사실, Repository와 상당히 유사한 기능을 하고있지만, DAO = Repository 라고 할 수는 없다.
둘 다 쿼리를 날려 CRUD를 하는것은 동일하지만, 개념적인 측면에서 차이가 있다고 한다.
이에 관해서는 정확히 이해가 되지 않아 조금 더 공부를 해보고 DAO와 Repository를 비교하는 글을 정리하며 개념을 잡아야겠다.
MVC패턴이라고 들어보았는가?
Model, View, Contorller
의 앞글자를 따서 MVC라고 한다.
사실 앞서 작성한 내용들이 전부 MVC패턴 중 View와 Conroller, Model에서 사용되는 전반적인 개념이다. 굳이 나누자면
DTO = View <-> Controller
Entity = Model <-> DB
DAO = Model <-> DB
이런식인거 같다. 이는 정확한지는 잘 모르겠어서 피드백을 남겨주면 좋을것같다.
이 MVC패턴에 관해서도 다른 글로 자세히 정리를 해보아야겠다.
위 MVC 를 보았을 때 Service는 Model에 속한다. 그래서 Service Model 이라고도 한다. 사실 이 Service가 어떤 역할인지 본다면 Controller <-> ServiceModel <-> DB
이 위치라고 해도 될것같다.
왜냐하면, Conroller에서는 요청만 받고 비즈니스로직은 Model에서 처리하는것이 MVC모델의 특징이라고 한다.
Service는 위에서 언급한것처럼 비즈니스 로직을 처리하는 Model이다.
그럼 이는 어떤식으로 코드가 작성이 될까?
필자는 아래와같이 작성을 한다.
우선, Service Interface를 만들고 해당 Interface를 상속받는 ServiceImpl Class를 만들어 사용을 한다.
public interface Service{
public LoginDTO.Response signinUser(LoginDTO.Request request);
}
public class ServiceImpl implements Service{
@Override
public ResponseEntity signinUser(LoginDTO.Request request){
//로그인로직
if(로그인성공){
return ResponseEntity.ok().body(response)
}else{
return ResponseEntity.badRequest().body("로그인실패")
}
}
}
이런 형태의 로직을 구현하게 된다.
그냥 어떤식으로 흘러가는지만 대강 구현을 해보았는데, 이렇게 DB와 직접 통신하여 값을 비교하고 불러오고 하는식의 로직이 이 Service Model에서 진행된다고 생각하면 된다.