본문 바로가기
[Spring Boot]

[Spring Boot] DTO, DAO, Vo

by 북방바다코끼리표범 2023. 10. 15.

복습

https://shins99.tistory.com/102

 

[Spring Boot] 스프링 부트에서 자주 사용하는 어노테이션

복습 https://shins99.tistory.com/97 [Spring Boot] 스프링 부트 시작하기( 기초 설정 방법) 복습 https://shins99.tistory.com/96 [Spring Boot] 스프링 부트 기초 스프링(Spring) 이란? - 자바 기반의 웹 어플리케이션을 만

shins99.tistory.com


DAO(Data Access Object)

- 실제로 DB의 data에 접근하기 위한 객체

  • 실제로 DB에 접근하여 data를 삽입, 삭제, 조회, 수정 등 CRUD 기능을 수행
  • Service와 DB를 연결하는 고리 역할을 함
  • Repository package가 바로 DAO
@Repository
@RequiredArgsConstructor
public class MemberRepository {

    private final EntityManager em;

    public void save(Member member) {
        em.persist(member);
    }

    public Member findOne(Long id) {
        return em.find(Member.class, id);
    }

    public List<Member> findAll() {
        return em.createQuery("select m from Member m", Member.class).getResultList();
    }

    public List<Member> findByName(String name) {
        return em.createQuery("select m from Member m where m.name =:name", Member.class)
                .setParameter("name", name)
                .getResultList();
    }
}

 

DTO(Data Transfer Object)

- 계층 간 데이터 교환을 하기 위해 사용하는 객체로, DTO는 로직을 가지지 않는 순수한 데이터 객체(Java Beans)

  • DTO는 즉, getter/setter 메서드만 가진 클래스를 의미
  • DB에서 데이터를 얻어서 Service나 Controller 등으로 보낼 때 사용
  • 즉 엔티티를 DTO 형태로 변환한 후 사용

예시 코드로 정리

  1. domain(Entity) logic
  2. DTO logic
  3. Controller logic

1) Entity가 있다고 가정

@Entity
@Getter
@Setter
public class Member {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
	private int age;

}

2) DTO class

    @Getter
    @Setter
    static class ResponseDto {
        private String name;
        private String result = "결과입니다.";

        public ResponseDto(Member member) {
            name = member.getName();
        }
    }

3)  Controller logic

    @PostMapping("api/useDTO")
    @ResponseBody
    public ResponseDto useDTO(@RequestParam String name, @RequestParam Long id) {
    	Member findMember = memberService.findOne(id);
        return new ResponseDto(findMember);
    }
    
    @PostMapping("api/notUseDTO")
    @ResponseBody
    public FindMember notUseDTO(@RequestParam String name, @RequestParam Long id) {
        Member findMember = memberService.findOne(id);
        return new FindMember(findMember);
    }

결과

useDTO 메서드는 Entitiy의 결과를 DTO로 변환하여 원하는 결과인 name과 result만 클라이언트에게 반환

하지만 notUseDTO는 Member엔티티의 모든 정보 즉, 엔티티 그 자체를 클라이언트에게 반환

현재 예시는 DTO를 Response에만 이용했지만 Request역시 적용 가능

 

VO(value Object)

- VO는 DTO와 달리 Read-Only속성을 지닌 값 오브젝트

- DTO setter를 가지고 있어서 값이 변할 수 있지만 VO의 경우에는 getter만 가지고 있어서 수정이 불가능

 

DTO와 VO의 차이점

- DTO는 인터턴스 개념

- DTO의 경우 데이터를 담는 그릇의 역할일 뿐 값은 그저 전달되어야 할 대상

 

- VO는 리터럴 값 개념

- VO는 값들에 대해 Read-Only를 보장해줘야 존재의 신뢰성이 확보됨

(값 자체에 의미가 있는 VO와 전달될 데이터를 보존해야 하는 DTO의 특성상 개념이 다름)

- VO의 핵심 : 두 객체의 모든 필드 값들이 동일하면 두 객체는 같음

 

 (완전히 값 자체 표현 용도로만 사용하는 게 목적이라면, 두 객체의 모든 필드 값들이 모두 같으면 같은 객체이도록 만드는 것(equals() 와 hashCode()의 오버라이딩)이 중요하지, 메소드는 어떤 메소드가 있든 말든 상관 없음)

 

DTO와 VO 차이

종류 용도 동등 결정 가변 / 불변 로직
DTO - 계층 간 데이터 전달 - 속성값이 모두 같아도 같은 객체가 아닐 수 있음 - setter 존재 시 가변,
- setter 비 존재 시 불변
- getter/setter 이외의 로직이 불필요함
VO - 값 자체를 표현 - 속성값이 모두 같으면 같은 객체 - 불변 - getter/setter 이외의 로직을 가질 수 있음