[BackEnd] DAO, DTO, Repository는 뭘까?

김재혁·2023년 11월 3일

BackENd

목록 보기
4/7

preview

Spring으로 어플리케이션에 백엔드를 구성할 때 다양한 패키지에 클래스들을 넣어 설계한다. Dao, Dto, Entity, Repository는 스프링 백엔드 어플리케이션을 설계해 봤다면 꼭 보는 패키지와 클래스명 애논테이션 이름이다. 이것들의 의미는 무엇일까?

Spring 웹 계층

스프링 웹계층이란 스프링 프레임워크에서 웹 애플리케이션을 개발하는 데 사용되는 계층이다. 이 계층은 주로 사용자 인터페이스 및 클라이언트와 상호 작용하며 HTTP 요청과 응답을 처리하는 역할을 한다.

Web Layer(Persistence Layer)

  • 흔히 사용하는 컨트롤러(@controller)와 JSP 등의 뷰 템플릿 영역
  • 이외에도 @Filter, 인터셉터, 컨트롤러 어드바이스 등 외부 요청과 응답에 대한 전반적인 영역을 이야기한다.
  • 브라우저상의 웹 클라이언트의 요청 및 응답을 처리한다

Sevice Layer

  • @Service 에 사용되는 영역
  • ControllerDao의 중간 영역에서 사용되어 두 계층이 직접적으로 통신하지 않게 됨
  • @Transactional이 사용되어야 하는 영역이기도 함 --> 원자성 보장

Repository Layer

  • DB와 같이 데이터 저장소에 접근하는 영역
  • DAO 영역
  • 데이터를 CRUD하는 계층으로 ORM 표준을 주로 사용한다

DTO

DTO는 말 그대로 데이터를 Transfer 하기 위한 객체이다. Controller에 요청을 보낼 때도 Request Dto 형식으로 데이터가 이동하고, Controller가 client에 응답을 보낼 떄도 Response Dto 형태로 데이터를 보내게 된다.

DTO는 로직을 갖고 잊지 않는 순수한 데이터 객체이며, 일반적으로 get/set 메서드만을 가진다. Setter는 변수가 가변이냐, 불변이냐에 따라 사용유무를 따진다(대부분 불변이라 생성자만을 사용하여 값을 할당하는 방법을 사용함)

Entity를 바로 사용하지 않고 DTO를 사용하는 이유

  1. View Layer와 DB Layer의 역할을 분리하기 위해서

    • 객체를 표현하기 위한 계층과 저장하는 계층의 역할을 분리하기 위해서 DTO를 사용한다.
  2. Entity 객체의 변경을 피하기 위하여

    • Entity 객체를 그대로 사용하면 프로그래머의 의도와 다르게 데이터가 변질될 수 있다.
  3. View와 통신하는 DTO 클래스는 자주 변경된다.

    • View와 통신하는 DTO 클래스, 예를들어 ResponseDTO, RequestDTO는 요구사항에 따라 자주 변경된다. 어떤 요청에는 특정 값이 추가될 수도 있고, 특정 값이 없을 수 도 있다. 따라서 Entity 클래스와 분리하여 관리해야 한다.

DAO

DAO는 말 그대로 실제 DB에서 객체에 접근하는 것을 말한다. DAO는 Service와 실제 DB를 연결하는 역할을 하게 된다. 즉 DB에서 데이터를 꺼내오거나 넣는 역할을 DAO가 담당한다.

@Repository
public class AirlineTicketJdbcTemplateDao implements AirlineTicketRepository{

    private JdbcTemplate jdbcTemplate;

    @Override
    public List<AirlineTicketFlightInfo> findAllAirlineTicketAndFlingInfo(Integer airlineTicketId) {
        return null;
    }

    public AirlineTicketJdbcTemplateDao(@Qualifier("jdbcTemplate2") JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    static RowMapper<AirlineTicket> airlineTicketRowMapper = (((rs, rowNum)  ->
            new AirlineTicket(
                rs.getInt("ticket_id"),
                rs.getNString("ticket_type"),
                rs.getNString("departure_loc"),
                rs.getNString("arrival_loc"),
                rs.getDate("departure_at"),
                rs.getDate("return_at"),
                rs.getDouble("tax"),
                rs.getDouble("total_price")
        )
                        )); //DB row 접근 

        public List<AirlineTicket> findAllAirlineTicketsWithPlaceAndTicketType(String likePlace, String ticketType){
            return jdbcTemplate.query("select * from airline_ticket "+
                    "where arrival_loc = ? AND ticket_type = ?", airlineTicketRowMapper, likePlace, ticketType);
        }
    }

JPA의 경우 Repository가 DAO의 역할을 한다고 볼 수 있다. 하지만 DAO와 Repository가 같은 것은 아니다.

DAO는 DB 혹은 다른 영속성 메커니즘에 대한 접근을 추상화해주는 역할을 한다. 예를들어 DAO를 쓰지 않는다면 DB 변경에대한 취약점, 어떤 DB를 쓰는지 노출, 서비스 계층에서 이를 직접적으로 변경 이라는 문제점들이 생긴다.

따라서 DB 객체에 접근하는 DAO를 따로 만들어주고 Application 계층은 어떤 DB를 사용하든지 상관없이 자신의 일만하면 된다. DAO는 DB를 사용한다면 보통 DB 테이블과의 매핑을 책임으로 가진다.


Repository

Repository는 DDD에서 등장한 개념이다. Repository는 DAO와 다르게 생성하는 경우가 DB 테이블이 기준이 아니다. Repository는 연관이 있고, 함께 변경되어야 하는 여러 도메인 모델 사이에서 이들의 진입점 역할을 할 수 있는 도메인 엔티티에 대해서만 Repository를 구현한다.

결론적으로 DAO는 DB에 조금 더 연관성이 있으며 Repository는 도메인 모델에 조금 더 연관되어 있다.

profile
아웃라이어 :)

0개의 댓글