[Java/Spring] 스프링 MVC 패턴(1) : Model - Entity, Repository, Service, Dto

SujiPark·2025년 2월 10일

Java

목록 보기
5/7

보통 프로젝트를 할 때 MVC 패턴으로 개발을 하는데, 이는 역할을 분리하여 개발한다는 것이다.

이렇게 해야 유지보수가 쉽고 Controller, Model, View를 독립적으로 개발할 수 있어 확장성이 높기 때문인데, 일단 MVC가 무엇인지 알아야 효율적으로 개발을 할 수 있으니 MVC가 무엇인지 알아보도록 하자!

📌 MVC(Model-View-Controller) 패턴이란?

소프트웨어 아키텍처 패턴 중 하나로, 애플리케이션의 역할을 Model-View-Controller 3가지로 분리하여 유지보수와 확장성을 높이는 구조

Spring Boot에서 기본적으로 MVC패턴을 사용해서 웹 애플리케이션을 개발한다.

Spring MVC의 동작 과정

  1. 사용자가 요청(URL 요청)
  2. DispatcherServlet(프론트 컨트롤러)가 요청을 가로챔
  3. 요청을 적절한 Controller에게 전달
  4. Controller는 요청을 처리하고, 필요한 데이터를 Service를 통해 조회
  5. Service는 데이터베이스와 연동되는 Repository를 호출
  6. Repository가 MySQL 등의 DB와 연결하여 데이터 조회 및 처리
  7. 조회한 데이터를 Model에 담아서 View(Thymeleaf)로 전달
  8. Thymeleaf 템플릿 엔진이 데이터를 화면에 렌더링
  9. 완성된 HTML이 사용자에게 응답으로 반환됨

아직 잘 이해가 되지 않을테니 밑에서 더 알아보도록 하자

📍 MVC 패턴의 개념

먼저 MVC란, 애플리케이션을 Model(모델) - View(뷰) - Controller(컨트롤러) 3가지 역할로 나누어 개발하는 구조를 말한다.

가장 먼저 Model에 대해 알아보자.

Model (모델)

  • 데이터를 처리하는 역할로, 데이터베이스와 연결되어 데이터를 저장하고 가공한다.
  • MVC 패턴에서 Model은 애플리케이션의 데이터를 다루는 모든 로직을 포함하는데,
    EntityDTO, Service, Repository가 포함된다.

1. Entity

개념

  • 데이터베이스의 테이블과 1:1 매핑되는 클래스이며 @Entity 어노테이션을 사용하여 정의한다.
  • 데이터 저장, 조회, 수정, 삭제 등을 수행하는 객체 자체이며 일반적으로 ServiceRepository에서 사용된다.

쉽게 말해 데이터베이스에 테이블, 즉 데이터가 있을 때, 우리는 작성한 클래스 위에 @Entity라는 어노테이션을 붙여서 이 클래스가 엔티티이고 해당 테이블과 매핑된다! 라고 선언해주는 것이다.

Entity의 특징

  • DB 테이블과 매핑되어 직접적인 데이터 저장소 역할을 한다.
  • @Entity, @Table, @Id, @Column 등의 JPA 어노테이션을 사용한다.

비즈니스 로직이 포함되지 않고, 데이터 자체를 표현하는 것이 목적이다!

import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    private String email;
    private String password;
}

예시 코드를 보면 @Entity 어노테이션으로 선언해준 것을 알 수 있다.

2. Repository

개념

  • Entity를 이용해 데이터베이스와 직접 소통하는 계층이다.
  • 데이터를 저장, 조회, 수정, 삭제(CRUD)하는 역할이며 Spring Data JPA를 사용하면 SQL을 직접 작성하지 않아도 자동으로 처리된다.

Repository의 특징

  • JpaRepository<Entity, ID 타입>을 상속하면 기본적인 CRUD 기능 제공
  • DB와의 직접적인 연동을 담당하며, Entity를 다룬다.

즉, Respository는 JPA를 사용하여 DB에 접근, 직접 상호작용하는 계층이며 Entity를 다루게 된다.

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
    // JpaRepository<User, Long>을 상속하면 기본 CRUD 메서드를 자동 생성
}


기본으로 제공되는 메서드는 다음과 같다.

📍 기본 제공 메서드

save(User user) : 사용자 저장

findById(Long id) : 특정 사용자 조회

findAll() : 모든 사용자 조회

deleteById(Long id) : 특정 사용자 삭제

count() : 총 사용자 수 반환

3. Service란?

개념

  • 비즈니스 로직을 처리하는 계층이다.
  • Repository를 통해 데이터베이스에서 값을 조회하거나, 가공하여 Controller에 전달한다.
  • 여러 Repository를 조합하여 복잡한 로직을 수행 가능

Service의 역할

  • Controller에서 받은 요청을 처리하고 Repository를 호출하여 DB와 연동한다.
  • 데이터를 가공하여 DTO로 변환 후 Controller에 반환한다.

즉, Controller와 Repository의 중간 통로 역할을 한다고 생각하면 된다.

import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // 모든 사용자 조회 (Entity → DTO 변환)
    public List<UserDTO> getAllUsers() {
        return userRepository.findAll()
                .stream()
                .map(user -> new UserDTO(user.getName(), user.getEmail()))
                .collect(Collectors.toList());
    }

    // 사용자 저장 (DTO → Entity 변환)
    public void saveUser(UserDTO userDTO) {
        User user = new User();
        user.setName(userDTO.getName());
        user.setEmail(userDTO.getEmail());
        user.setPassword("defaultPassword"); // 실제 환경에서는 암호화 필요
        userRepository.save(user);
    }
}
  • getAllUsers()EntityDTO로 변환 후 반환
  • saveUser()DTOEntity로 변환 후 저장
  • ControllerService의 메서드를 호출하여 데이터를 처리한다.

4. DTO란?

개념

  • 계층 간 데이터 전송을 위해 사용하는 객체이다.
  • Entity와 달리 DB와 직접적인 연동이 없고, 필요한 데이터만 포함한다.
  • Entity의 민감한 정보를 숨기거나, 가공된 데이터를 전송하는 역할이다.

DTO의 역할

  • Controller ↔ Service ↔ Repository 간의 데이터 전송
  • Entity의 불필요한 데이터를 숨기고, 필요한 데이터만 포함
  • 보안 강화 (비밀번호 같은 민감한 정보를 제외 가능)
  • API 응답 시 DTO 사용으로 유연한 데이터 반환 가능
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class UserDTO {
    private String name;
    private String email;

    public UserDTO(String name, String email) {
        this.name = name;
        this.email = email;
    }
}

Entity 중 민감하지 않은 정보만 뽑아 정보를 전송하는 클래스라고 생각하면 된다.

  • Entity와 다르게 password 필드가 없음
  • View에서 사용할 데이터만 포함
  • Service에서 Entity → DTO 변환 후 반환

0개의 댓글