서비스

suhan cho·2022년 7월 7일
0

Service

  • 질문 목록의 제목 링크를 누르면 질문 상세 화면이 보이게 할 것이다.

  • 이전 질문 목록 데이터를 QuestionController에서 QuestionRepository를 직접 사용하여 조회
    -> 하지만 대규모 프로젝트는 리포지토리 직접 호출 않고 서비스를 두어 데이터를 처리(서비스 = 스프링에서 데이터 처리를 위한 클래스)

서비스가 필요한 이유

모듈화

  • 예를 들어 어떤 컨트롤러가 여러개의 리포지터리를 사용하여 데이터 조회한 후 가공하여 리넡한다고 가정
  • 이런 기능을 서비스로 만들어 두면 컨트롤러에서는 해당 서비스 호출하여 사용하면 된다.
  • 구현 안할 시 필요할 때 마다 중복으로 구현해야 한다.

보안

  • 컨트롤러는 리포지터리 없이 서비스를 통해서만 데이터베이스에 접근하도록 구현하는 것이 보안상 안전
  • 컨트롤러를 제어할 수 있게 되더라도 리포지터리 직접 접근 불가

엔티티 객체와 DTO 객체의 변환

  • Question, Answer 클래스는 엔티티 클래스이다.

  • 엔티티클래스는 데이터베이스와 직접 맞닿아 있는 클래스이기 때문에 컨트롤러나 타임리프 같은 템플릿 엔진에 전달하여 사용하는 것이 좋지 않다.

  • 컨트롤러나 타임리프에서 사용하는 데이터 객체는 속성을 변경하여 비즈니스적인 요구를 처리해야 하는 경우가 많은데 엔티티를 직접 사용하여 속성을 변경한다면 테이블 컬럼이 변경될 수 있다.

  • 그러므로, Question,Answer 같은 엔티티 클래스는 컨트롤러에 사용 할 수 없게 설계하는 것이 좋다.-> 대신 사용할 DTO(Data Transger Object)클래스 필요

  • 엔티티 객체를 DTO객체로 변환하는게 필요(서비스에서 한다)

서비스 만들기

@Service
public class QuestionService {
    
    @Autowired
    private final QuestionRepository questionRepository;

    public QuestionService(QuestionRepository questionRepository) {
        this.questionRepository = questionRepository;
    }
    
    public List<Question> getList(){
        return this.questionRepository.findAll();
    }
}
  • @Service 애너테이션을 붙여서 서비스를 만들면 된다.
  • questionRepository객체는 생성자 방식으로 DI규칙에 의해 주입
  • 질문 목록을 조회하여 리턴하는 getList메서드를 추가
@Controller
public class QuestionController {

    @Autowired
    private final QuestionService questionService;

    public QuestionController(QuestionService questionService) {
        this.questionService = questionService;
    }

    @RequestMapping("/question/list")
    public String list(Model model){
        List<Question> questionList = this.questionService.getList();
        model.addAttribute("questionList", questionList);
        return "question_list";
    }
    
}

  • 같은화면 출력
  • controller -> service -> repository구조로 데이터 처리
profile
안녕하세요

0개의 댓글