DAO ( Data Access Object )

정웅·2025년 11월 27일

데이터베이스

목록 보기
3/5

1. DAO 란?

DAO = Data Access Object

"DB에 직접 접근해서 CRUD 하는 역할만 전담시키는 객체"

전통적인 3계층 구조에서

  • Controller : 요청 받고 응답 만드는 애
  • Service : 비즈니스 로직 (트랜잭션, 도메인 규칙)
  • DAO : DB 쿼리 날리는 애 (Select, Insert, Update, Delete)

예전 스타일(특히 순수 JDBC, MyBatis 쓸 때)에는 이렇게 많이 썼다.

public class UserDao {

    private final DataSource dataSource;

    public UserDao(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public User findById(Long id) {
        // 커넥션 열고, PreparedStatement 만들고, ResultSet 파싱하고...
    }

    public void save(User user) {
        // INSERT 쿼리 실행
    }
}
  • DAO는 “DB 테이블/엔티티 1개당 1개” 느낌으로
  • 순수하게 데이터 액세스 코드만 모아놓은 계층이다.

지금 나의 Spring Data JPA의 XXXRepository들이 사실상 DAO 역할을 하는 애들이라고 보면 된다.

public interface TrackingLinkRepository extends JpaRepository<TrackingLink, Long> {
    Optional<TrackingLink> findBySlug(String slug);
}

이게 전통적인 용어로는 TrackingLinkDao이다.

2. “요새는 DTO, DAO 잘 안 쓰지 않아?” -> 용어/쓰기 방식이 바뀐 것

2-1) DAO → Repository로 이름/역할이 바뀐 느낌

스프링 세상(특히 JPA)에서는 보통:
DAO라는 말보다는 Repository 라는 말을 더 많이 씀

이유:
DDD(Domain-Driven Design) 영향
“엔티티의 컬렉션을 캡슐화하는 저장소” 라는 의미 강조

내부의 “데이터 접근 방법(=SQL, JPA, 캐시, 네트워크 등)”은

Repository 안에 숨겨져 있고(캡슐화)

바깥(서비스, 컨트롤러)은 “메서드”만 보는 구조

그래서:
예전: UserDao, OrderDao
요즘: UserRepository, OrderRepository

역할은 비슷하다
→ “DB에 있는 데이터를 가져오고, 저장하고, 지우는 계층”

단지:

  • 스프링 데이터 JPA가 CrudRepository, JpaRepository 같은 걸 제공해서
  • 인터페이스만 만들어도 구현체를 자동 생성해주니까
  • "DAO 클래스를 직접 구현하는 일"이 줄어든 거다.

    "DAO라는 이름을 잘 안쓰지,
    DAO에 해당하는 레이어(Repository)는 여전히 필수이다.

2-2) DTO는 여전히 매우 많이 씀 (오히려 더 중요해짐)

DTO = Data Transfer Object

“계층 간에 데이터를 전달할 때 사용하는 순수 데이터용 객체”
보통 게터/세터만 있고, 비즈니스 로직 없음.
요즘 많이 쓰는 DTO 예시:

  • Request DTO: 클라이언트 → 서버 들어올 때

    • TrackingLinkCreateRequest

    • UserSignUpRequest

  • Response DTO: 서버 → 클라이언트 보낼 때

    • TrackingLinkResponse

    • UserProfileResponse

이유:

1) 엔티티를 그대로 노출하면 위험

  • API 스펙이 DB 설계에 종속됨
  • 필드가 늘어나고, 민감정보(password, 내부용 필드등)도 같이 나갈 수 있다.
  • 엔티티 필드 이름/구조 바꾸면 API도 다 깨짐

2) 계층 분리 & 유지보수

  • 엔티티는 "DB와 도메인 모델" 중심으로 설계
  • DTO는 "클라이언트가 필요로 하는 화면/응답 형태"로 설계
  • 같은 엔티티라도, 화면마다 다른 DTO로 뽑아낼 수 있음 (목록용, 상세용 등)

그래서 요즘 트렌드는 오히려:
엔티티는 엔티티대로 깔끔하게
요청/응답용 DTO는 DTO대로 깔끔하게
둘 사이 매핑은 Service or Mapper 계층에서 처리

public TrackingLinkResponse toResponse(TrackingLink entity) {
    return new TrackingLinkResponse(
        entity.getId(),
        entity.getSlug(),
        entity.getFinalUrl(),
        entity.getCreatedAt()
    );
}

=> Entity를 밖으로 그대로 내보내지 말고 DTO로 감싸라

3. 헷갈렸던 포인트

예전(고전적인 3계층 + JDBC/MyBatis)
Controller
Service
DAO (직접 구현)
DTO (있긴 한데 엔티티와 혼용되는 경우도 많았음)
Entity/VO 같은 이름들도 섞임

요즘(Spring + JPA + DDD 영향)
Controller (Web Layer: Request/Response DTO)
Service (비즈니스 로직, 트랜잭션 경계)
Repository (DAO 역할)
Entity (도메인 모델)
DTO (API, View, Command/Query 용도별로 따로 정의)

4. 요약

DAO

  • DB에 접근해서 CRUD를 수행하는 데이터 액세스 계층 객체
  • 요즘 스프링에서는 이 역할을 Repository 가 하고,
  • JpaRepository, CrudRepository 를 상속받아서 인터페이스만 작성하면 DAO 구현체를 대신 만들어줌.

요즘은 DTO, DAO 잘 쓰는가

  • DAO라는 이름을 잘 안 쓸 뿐이고,
    그 레이어는 여전히 있고, 이름만 Repository로 바뀐 느낌.
  • DTO는 오히려 더 중요해졌고,
    엔티티를 그대로 외부에 내보내지 말고 DTO로 감싸서 API를 설계하는 게 요즘 흔한 패턴.
profile
즐거운 개발 :) 신입 서버 개발자입니다

0개의 댓글