[LG CNS AM Inspire Camp 1기] BE - DAO vs DTO vs Entity vs VO

이슬아·2025년 1월 31일

LG CNS AM Inspire Camp 1기

목록 보기
16/20
post-thumbnail

📍 DAO (Data Access Object)

  • DAO는 실제로 DB의 data에 접근하기 위한 객체
  • 실제로 DB에 접근하여 data를 삽입, 삭제, 조회, 수정 등 CRUD 기능을 수행 (SQL 실행)

✔ 쉽게 말하면?
"DB와 직접 소통하는 직원"
👉 회사(애플리케이션)에서 창고(DB)에 물건(데이터)을 넣고 빼는 직원
👉 SQL을 실행해서 데이터를 읽고, 쓰고, 수정, 삭제하는 역할

public class UserDAO {
    public User getUserById(int id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper());
    }
}

📍DTO (Data Transfer Object)

  • DTO는 계층 간 데이터 교환을 하기 위해 사용하는 객체로, DTO는 로직을 가지지 않는 순수한 데이터 객체(Java Beans)
  • getter/setter 메서드만 가짐
  • DB에서 데이터를 얻어서 Service나 Controller 등으로 보낼 때 사용
    즉 엔티티를 DTO 형태로 변환한 후 사용함

    ✔ 쉽게 말하면?
    "택배 상자 📦"
    👉 DAO가 창고(DB)에서 가져온 물건을 상자(DTO)에 담아서 배달(Service → Controller)
    👉 데이터를 전달하기 위한 객체 (DB와 직접 연결 X)

📍 Entity

  • 실제 DB 테이블을 표현하는 객체
  • Entity는 DB 테이블과 1:1 매핑되는 객체로, JPA에서 데이터를 저장하고 관리하는 핵심 클래스
  • Entity 객체를 통해 DB에 데이터를 저장, 조회, 수정, 삭제할 수 있으며, 비즈니스 로직을 포함할 수 있음.

    ✔ 쉽게 말하면?
    "창고(DB) 안에 있는 실제 물건"
    👉 DAO(직원)가 창고(DB)에서 꺼내오는 진짜 상품(데이터)
    👉 JPA를 사용하면 엔티티를 통해 DB 테이블에 직접 접근 가능

예시

아래와 같은 Entity가 있을 때

@Entity
@Getter
@Setter
public class Member {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String name;
	private int age;
 
}

✔ DB 테이블과 매핑되는 객체 (JPA 엔티티)
✔ 엔티티는 비즈니스 로직을 위한 객체이므로 API 응답에 직접 사용하면 위험하다.

➡️ DTO 사용

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

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

✔ DTO는 클라이언트에게 필요한 데이터만 포함
✔ result = "결과입니다."처럼 DTO 내부에서 추가적인 가공 가능

Controller

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

✔ DTO를 사용하여 name과 result만 반환 (불필요한 데이터 제거)
엔티티 전체를 반환하면 id, name, age가 모두 클라이언트에 노출되어 보안 문제 발생 가능

📍 VO (Value Object)

  • VO(Value Object)는 한 번 생성되면 값이 변하지 않는 불변 객체로, Read Only의 목적이 강하고 데이터를 보관하는 용도로 사용됨
  • DTO와 비슷하지만, 값을 변경할 수 없다는 점이 핵심 차이점
  • DTO는 주로 데이터 수집의 용도가 좀 더 강하다

예시를 들자면, 웹 화면에서 로그인하는 정보는 DTO로 처리하고, 테이블과 관련된 데이터는 VO로 처리한다.

✔ 쉽게 말하면?
"택배 상자 📦인데, 안에 담긴 물건을 절대 바꿀 수 없는 상자"
👉 한 번 값이 설정되면 변경되지 않음 (Immutable)
👉 equals()와 hashCode()를 오버라이딩하여 값 비교 가능

public class UserVO {
    private final Long id;
    private final String name;
    private final int age;

    public UserVO(Long id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Long getId() { return id; }
    public String getName() { return name; }
    public int getAge() { return age; }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserVO userVO = (UserVO) o;
        return age == userVO.age &&
                id.equals(userVO.id) &&
                name.equals(userVO.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, age);
    }
}

✔ final 키워드를 사용하여 값 변경 방지
✔ Setter 없이 생성자로만 값 설정 (불변 객체 유지)
✔ equals()와 hashCode()를 오버라이딩하여 값 비교 가능

관계 정리

1️⃣ Entity = 창고(DB)에 저장된 실제 물건
➕ 정확히는 Entity는 데이터(실제 물건)를 담는 틀이며, 데이터는 그 틀을 따라 만들어진 개별적인 값 (레코드)
2️⃣ DAO = 창고(DB)에서 물건(데이터)을 가져오고 넣는 직원
3️⃣ DTO = 창고에서 꺼낸 물건을 담아서 배달하는 택배 상자 (변경 가능)
4️⃣ VO = 값이 변하지 않는 특수한 택배 상자 (Immutable, 변경 불가능)

0개의 댓글