[코드로 배우는 스프링부트 웹 프로젝트] - 프로젝트 구조 만들기(3) - DTO, Service계층 생성

Jongwon·2022년 12월 26일
0

DTO(Data Transfer Object)

실제로 컨트롤러나 서비스 계층 사이에서나, 컨트롤러와 프론트엔드 사이의 데이터 전송은 엔티티를 직접 사용하는 방식이 아닌 DTO를 통해 이루어집니다. 앞선 글에서 언급했듯이 엔티티는 직접적인 수정을 다루기엔 위험하기 때문에, DTO를 통해 Getter/Setter처리를 합니다.

GuestbookDTO

package org.zerock.guestbook.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class GuestbookDTO {

    private Long gno;
    private String title;
    private String content;
    private String writer;
    private LocalDateTime regDate, modDate;
}

위와 같이 GuestbookDTO를 생성합니다.

그리고 서비스 계층도 생성합니다.

GuestbookService

package org.zerock.guestbook.service;

import org.zerock.guestbook.dto.GuestbookDTO;

public interface GuestbookService {
    Long register(GuestbookDTO dto);
}

GuestbookServiceImpl

package org.zerock.guestbook.service;

import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.zerock.guestbook.dto.GuestbookDTO;

@Service
@Log4j2
public class GuestbookServiceImpl implements GuestbookService{
    
    @Override
    public Long register(GuestbookDTO dto) {
        return null;
    }
}

다음으로는 DTO를 엔티티로 변환하는 작업이 필요합니다. 이 과정은 ModelMapper나 MapStruct와 같은 라이브러리를 이용한다면 자동생성되는 매퍼 클래스를 이용할 수도 있지만 이 책에서는 직접 변환하는 방식을 채택하였습니다.


public interface GuestbookService {
    Long register(GuestbookDTO dto);
    
    //아래 매퍼(dto->entity) 메서드 추가
    default Guestbook dtoToEntity(GuestbookDTO dto) {
        Guestbook entity = Guestbook.builder()
                .gno(dto.getGno())
                .title(dto.getTitle())
                .content(dto.getContent())
                .writer(dto.getWriter())
                .build();
        return entity;
    }
}

인터페이스 레벨에서 구현해놓았기 때문에 default 메서드를 사용합니다.

이제 이를 서비스 구현체에 적용해보겠습니다.

@Service
@Log4j2
public class GuestbookServiceImpl implements GuestbookService{

    @Override
    public Long register(GuestbookDTO dto) {
        log.info("DTO--------------------");
        log.info(dto);

        Guestbook entity = dtoToEntity(dto);
        log.info(entity);
        
        return null;
    }
}

일단 서비스에서 dto를 entity로 변환해주는 작업을 했는데, 이것이 정상 동작하는지 테스트를 통해 확인해보겠습니다.

GuestbookServiceTests

package org.zerock.guestbook.service;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.zerock.guestbook.dto.GuestbookDTO;

@SpringBootTest
public class GuestbookServiceTests {

    @Autowired
    private GuestbookService service;

    @Test
    public void testRegister() {

        GuestbookDTO guestbookDTO = GuestbookDTO.builder()
                .title("Sample title.....")
                .content("Sample content.....")
                .writer("user0")
                .build();

        System.out.println(service.register(guestbookDTO));
    }
}

다음으로는 Service에서 Repository로 Entity를 넘겨 저장하도록 ServiceImpl을 수정하겠습니다.

@Service
@Log4j2
@RequiredArgsConstructor  //추가
public class GuestbookServiceImpl implements GuestbookService{

    //추가
    private final GuestbookRepository repository;

    @Override
    public Long register(GuestbookDTO dto) {
        log.info("DTO--------------------");
        log.info(dto);

        Guestbook entity = dtoToEntity(dto);
        log.info(entity);
        
        //추가
        repository.save(entity);
        return entity.getGno();
    }
}

스프링 빈에 등록되어있는 GuestbookRepository@RequiredArgsConstructor를 통해 의존성 주입을 하였습니다. 이는 final로 정의된 repository에 대해 자동으로 생성자를 만들어 초기화해주는 어노테이션입니다.

다시한번 테스트 코드를 실행해보면 아래와 같이 데이터베이스에 저장되고, gno값인 301을 반환한 것을 확인할 수 있습니다.

profile
Backend Engineer

0개의 댓글