[Spring] DAO, DTO, Repository

이혜지·2022년 2월 12일
2

Spring

목록 보기
14/15

스프링 초보 개발할때 entity, repository, service, controller만 알고 개발하고 있었는데,
다른 사람들이 개발한것을 참고해보니 DTO라는 이름을 많이 사용하는것을 보고 알아보기로했다.

DAO, DTO, Repsitory, Entity Class를 이해하기

일반적으로 스프링 프로젝트 파일에 이름을 정할 때, DTO, Repository, Entity등의 이름이 들어가는 것을 알 수 있다. 이 정의에 대해 더 알아보자.

스프링을 사용한 웹앱의 경우 DAO, DTO, Repository, Entity를 사용하여 데이터를 다루며 스프링부트의 경우 내장 톰캣을 통해 서블릿을 관리하고 이를 컨트롤러에서 각 어노테이션을 통해 매핑한다.

Repository

  • MVC 패턴에서 모델에 해당하는 부분으로 POJO(plain old java object)로는 접근불가능하다.
  • Persistence Layer와 1:1 매칭이 가능하다.
  • Java Persistence API 구현체를 통해서 자바 객체에 접근할 수있다.
@Repository
@RequiredArgsConstructor
public class MemberRepository {
	private final EntityManage em;
    
    public void save(Member member) {
    	em.persist(member);
    }
}

해당 코드는 JPA 구현체가 Entity Model 객체를 사용해서 DB에 접근한다.

DAO(Data Access Object)

  • 원래 DB의 데이터(필드)와 프로그래밍 언어는 패러다임의 불일치로 인해 사용할 수 없다. 이를 원래 사용하려면 별도의 SQL을 작성해서 SQL을 객체의 필드에 하나씩 매핑하거나 순수한 SQL을 작성하여 사용해야 한다.

Entity

  • 하지만 별도의 Entity Class를 사용해서 클래스를 테이블과 1:1 매칭할 수 있다. 이러한 Entity Class를 도메인이라고 하며 가장 DB와 가까운 클래스이다.
@Entity
@Getter
public class Member {
	@Id @GeneratedValue
    @Column(name = "member_id")
    private Long id;
    
    @NotEmpty
    @NotNull
    private String name;
    
    @Embedded 
    private Address address;
    
    @JsonIgnore
    @OneToMany(mappedBy = "member")
    private List<Order> orders = new ArrayList<>();
}

다음은 예시 코드

  • Entity의 각 필드는 DB 테이블과 1:1 매칭되며 PK를 가진다.
  • Entity는 순수한 도메인 로직과 비즈니스 로직만 가지고 있어야한다.
  • Entity는 DB의 데이터를 전달해주고 Service에서 사용할 비즈니스 로직만을 가져야한다.
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {
	private final MemberRepository memberRepository;
}

다음 코드는 서비스 계층의 Repository를 사용한 코드이다.

DTO(Data Transfer Object)

  • Entity를 통해 DB에서 데이터를 꺼내왔지만 데이터를 접근해야하는 경우 문제가 있다.
  • Controller와 Presentation Layer는 클라이언트와 직접 만나며, Entity는 프레젠테이션 계층과 완전히 분리되어야 한다.
  • 이러한 경우에 DTO를 사용한다.
@Data
@AllArgsConstructor
static class MemberDto {
	private String name;
    private Address address;
}

이러한 경우 다음과 같이 DTO를 사용한다.

특징은 다음과 같다.

  • Getter/Setter가 없다.
  • Wrapping된 순수한 데이터 객체
  • Entity에 직접 접근하지 않으므로, Entity 변경시, DTO만 변경하면 된다.

결론

정리하자면 스프링 프로젝트는 다음과 같은 구조를 가진다.

구성은 다음 4개이다.

Domain(Entity)

@Entity
@Getter @Setter
public class Member {
	@Id @GeneratedValue
    @Column(name = "member_id")
    private Long id;
}
  • DB 테이블과 1:1 매칭된다.

Repository(DAO)

@Repository
@RequiredArgsConstructor
public class MemberRepository {
	private final EntityManager em;
}
  • Entity를 통해 데이터를 DB에 저장한다.
  • 엔티티는 DB의 데이터와 매칭되는 것
  • 실제 DB에 데이터를 저장하는 건 Repository 클래스의 Entity Manager를 통해 이루어진다.

Service

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {
	private final MemberRepository memberRepository;
}
  • 프레젠테이션(뷰)에서 엔티티에 직접 접근하지 않고 비즈니스 로직을 처리할 수 있도록하는 계층이다.
  • Repository에 정의된 비즈니스 로직을 처리하거나 엔티티에 접근한다.

Controller

@RestController // Response + Request
@RequiredArgsConstructor
public class MemberApiController {
	private final MemberService memberService;
    
    @GetMapping("api/v1/members")
    public Result<List<MemberDto>> memberV2() {
    
    }
}
  • 프레젠테이션 계층으로 클라이언트의 요청을 처리한다.
  • 엔티티는 서비스에 의해 추상화되어 직접 접근 불가능하다.
  • 서비스에 정의된 비즈니스 로직을 호출한다
  • ResponseBody에 데이터를 담아 반환해준다.

출처
https://azderica.github.io/00-java-repositorys/

profile
공유 문화를 지향하는 개발자입니다.

0개의 댓글