단순히 계좌 정보를 조회하거나 저장하는 기능을 구현하는 것을 넘어, Spring MVC의 전체 요청 처리 과정을 직접 구현하였다. 사용자가 브라우저에서 요청을 보내면 Controller가 이를 받아 Service를 호출하고, Service는 Repository를 통해 데이터베이스와 통신한 뒤 결과를 다시 Controller와 View(JSP)로 전달하는 전체 흐름을 경험할 수 있었다.
또한 DTO와 Entity를 분리하고, Repository 패턴과 Service 계층을 적용하면서 객체지향 설계 원칙(SRP, 역할 분리)이 실제 프로젝트에서 왜 중요한지 이해할 수 있었다.
이번 실습은 Spring Framework가 단순히 코드를 줄여주는 프레임워크가 아니라, 유지보수성과 확장성을 고려한 구조를 제공하는 프레임워크라는 점을 배우는 과정이었다.
| 학습 내용 | 상세 내용 |
|---|---|
| Spring MVC 흐름 | 브라우저 요청부터 JSP 응답까지 전체 과정을 이해하였다. |
| 계층 구조 | Controller → Service → Repository → Database 순서로 동작한다. |
| DTO 변환 | 요청 DTO와 응답 DTO를 분리하여 사용하였다. |
| JdbcTemplate | Repository에서 데이터베이스와 통신하였다. |
| View 출력 | Controller가 Model을 통해 JSP에 데이터를 전달하였다. |
Browser
↓
DispatcherServlet
↓
Controller
↓
Service
↓
Repository
↓
Database
↓
Repository
↓
Service
↓
Controller
↓
JSP
↓
Browser
이번 프로젝트는 모든 요청이 위 구조를 따라 처리된다.
사용자가
이름 입력
↓
등록 버튼 클릭
을 수행하면
다음과 같은 과정이 실행된다.
HTML Form
↓
POST /
↓
MainController
↓
AccountFormDTO 생성
↓
BankService.makeAccount()
↓
Account Entity 생성
↓
Repository.save()
↓
JdbcTemplate.update()
↓
INSERT SQL
↓
Database
Controller에서는
@ModelAttribute
를 통해 HTML Form 데이터를 AccountFormDTO로 자동 변환한다.
Service에서는 DTO를 Entity로 변환한 뒤 Repository에 저장을 요청한다.
Repository에서는
INSERT INTO accounts(name)
VALUES(?)
를 JdbcTemplate로 실행하여 데이터베이스에 저장한다.
조회는 다음과 같이 진행된다.
GET /account/3
↓
AccountController
↓
findAccount()
↓
Repository.findById()
↓
SELECT SQL
↓
Database
↓
Account Entity
↓
AccountViewDTO
↓
Model
↓
account.jsp
Repository는 Entity를 반환하고,
Service는
AccountViewDTO.fromEntity(...)
를 이용하여 화면에 필요한 DTO로 변환한다.
수정은 조회보다 조금 더 많은 단계가 존재한다.
사용자 입력
↓
POST /account/{id}
↓
Controller
↓
AccountUpdateDTO
↓
Repository.findById()
↓
Entity 수정
↓
Repository.update()
↓
UPDATE SQL
↓
Database
Service에서는
먼저 기존 Entity를 조회한다.
그 이후
account.setName(...)
으로 값을 변경한 뒤
Repository.update()를 호출한다.
삭제 과정은 가장 단순하다.
GET /account/3/delete
↓
Controller
↓
Service
↓
Repository
↓
DELETE SQL
↓
Database
Repository에서는
DELETE FROM accounts
WHERE id=?
를 수행한다.
브라우저
↓
DispatcherServlet
↓
Controller
↓
Service
↓
Repository
↓
JdbcTemplate
↓
Database
↓
Repository
↓
Service
↓
Controller
↓
Model
↓
JSP
↓
브라우저
이 흐름이 Spring MVC 프로젝트의 핵심이라는 것을 이해하였다.
| 계층 | 역할 |
|---|---|
| Browser | 사용자 요청 |
| Controller | 요청 처리 및 View 연결 |
| Service | 비즈니스 로직 수행 |
| Repository | 데이터베이스 접근 |
| Database | 데이터 저장 |
| JSP | 사용자 화면 출력 |
각 계층이 자신의 역할만 수행하도록 설계되어 있기 때문에 유지보수가 쉬워진다.
| 기존 방식 | Spring MVC |
|---|---|
| main()에서 모든 작업 수행 | 계층별 역할 분리 |
| SQL 직접 실행 | Repository 담당 |
| 객체 생성 직접 수행 | Spring Bean 관리 |
| Request 직접 처리 | 자동 바인딩 |
| View 직접 연결 | ViewResolver 사용 |
| 느낀 점 | 내용 |
|---|---|
| Spring MVC | 전체 요청 흐름을 직접 구현해 보니 각 계층의 역할이 명확하게 이해되었다. |
| 객체지향 | 하나의 클래스가 하나의 책임만 가지도록 설계하는 이유를 체감하였다. |
| 유지보수 | 역할을 분리하면 기능을 수정할 때 다른 계층에 영향을 거의 주지 않는다는 점을 알게 되었다. |
| Spring Framework | 단순한 라이브러리가 아니라 애플리케이션 구조를 설계하도록 도와주는 프레임워크라는 점을 이해하였다. |
| 배운 점 | 내용 |
|---|---|
| MVC 구조 | 요청 처리 흐름을 계층별로 나누면 코드의 가독성과 유지보수성이 향상된다. |
| Service Layer | 비즈니스 로직을 한곳에서 관리하면 Controller가 단순해진다. |
| Repository Pattern | 데이터 접근을 분리하면 데이터베이스 구현이 변경되어도 다른 계층에 영향을 주지 않는다. |
| DTO | 요청과 응답을 분리하면 보안성과 확장성이 향상된다. |
| JdbcTemplate | 반복적인 JDBC 코드를 줄이고 개발 생산성을 높여준다. |
이번 Spring MVC 프로젝트는 단순히 CRUD 기능을 구현하는 것이 아니라 웹 애플리케이션이 요청을 처리하는 전체 구조를 이해하는 과정이었다. Controller는 사용자의 요청을 받아 적절한 Service를 호출하고, Service는 비즈니스 로직을 수행하며 Repository를 통해 데이터베이스와 통신한다. Repository는 JdbcTemplate을 활용하여 SQL을 실행하고, 조회한 Entity는 필요한 정보만 담은 DTO로 변환되어 다시 Controller와 JSP로 전달된다.
이번 실습을 통해 Controller → Service → Repository → Database라는 계층형 구조와 MVC 패턴의 장점을 체감할 수 있었으며, 역할을 명확히 분리하는 설계가 유지보수성과 확장성을 높인다는 점을 이해하게 되었다. 또한 DTO와 Entity를 분리하고 JdbcTemplate, RowMapper, @Transactional을 활용하는 방법을 익히면서 앞으로 Spring Data JPA, MyBatis, 대규모 Spring Boot 프로젝트를 학습하는 데 필요한 핵심 기반을 다질 수 있었다.