본문 바로가기
Spring

2022-09-28 스프링 (서비스)

by allwing12 2022. 9. 28.

서비스를 사용하는 이유는 여러개의 리포지터리를 사용해서 데이터를 조회하고

가공하고 리턴한다고 했을 때 여러개를 만들고 만약 이름을 변경한다고 했을 때에는

하나하나 다 변경을 해야한다, 여러개를 만든다는 것은 애초에 기능을 중복으로 구현한다는 것이다.

그렇기 때문에 오히려 더 비효율적으로 일을 해야하게 될 수 있기 때문이다.

 

그리고 보안상의 문제인데 컨트롤러는 리포지터리 없이 서비스를 통해서만 데이터베이스에 접근하도록

구현하는 것이 보안상 안전하다는 이유인데 이렇게 하면 해커가 해킹을 통해서 컨트롤러를

제어할 수 있게 되어도 리포지터리에는 직접 접근할 수 없어져서이다.

 

그리고 마지막으로는 엔티티 객체와 DTO 객체의 변환되는 부분 때문인데

예를 들어 지금 수업 때 하는 Question 과 Answer 클래스는 엔티티클래스이다.

엔티티 클래스는 데이터베이스와 직접 맞닿는 클래스이기 때문에 컨트롤러나 타임리프 같은

템플릿 엔진에 전달하여 사용하는 것은 그렇게 좋지 않다고 한다.

 

직접 사용해서 속성을 변경한다면 테이블 컬럼이 변경 되어서 엉망이 될 수 있기 때문이라고 한다.

그렇기 때문에 엔티티 클래스는 컨트롤러에서 사용할 수 없게끔 설계하는 것이 좋다고 한다.

그래서 필요한게 DTO 클래스가 필요하며 엔티티 객체를 DTO 객체로 변환하는 작업도 필요하다고 한다.

이 변환하는 일을 서비스에서 처리하며 서비스는 컨트롤러와 리포지터리의 중간에 있어서

엔티티 객체와 DTO 객체를 서로 변환해서 서로에게 전달하는 역할을 한다고 한다.

 

 

package com.mysite.sbb.question.Service;

import com.mysite.sbb.question.dao.QuestionRepository;
import com.mysite.sbb.question.domain.Question;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

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

    public List<Question> getList() {
        return questionRepository.findAll();
    }
}

 

우선 Question에 Service라는 폴더를 만들어서 QuestionService 라는 클래스를 만들어서

위와 같은 코드를 작성을 했다. 

스프링의 서비스로 만들기 위해서 클래스 명 위에 @Service 애너테이션을 붙였다.

그리고 추가한 건 getList 메서드이며 이전 컨트롤러에서 지포지터리를 사용했던 부분을 그대로 옮겼다.

 

 

package com.mysite.sbb.question.Controller;

import com.mysite.sbb.question.Service.QuestionService;
import com.mysite.sbb.question.domain.Question;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
@RequiredArgsConstructor
public class QuestionController {

    private final QuestionService questionService;

    @RequestMapping("")
    public String index() {
        return "redirect:/question/list";
    }

    @RequestMapping("/question/list")
    public String list(Model model) {

        List<Question> questionList = questionService.getList();
        model.addAttribute("questionList", questionList);
        return "question_list";
    }

}

 

 

그리고 public String list에 다가 questionService.getList를 추가를 했고

Private final 을 QuestionRepository가 아닌 QuestionService로 변경을 했다.

이렇게 해서 실행을 해보면 동일한 화면을 볼 수 있으며 여기에서 처리되는 방식은

Controller -> Service -> Repository 순으로 데이터가 처리가 된다.

 

 

 

 

 

댓글