[멋사 클라우드 5기] Day 15 - MVC & JDBC 구조 톺아보기

2026. 2. 11. 03:08·Learning Log

MVC 패턴과 JDBC가 적용된 프로젝트를 실습하면서 배운 내용들을 정리해본다.

중요한 포인트는 아래 두 가지이다.

  • 호출 흐름이 어떻게 이루어지는지
  • 이때 각 레이어에서 어떤 역할을 수행하는지

1. 전체 구조 파악하기


2. 레이어 역할

레이어 역할

  • View: 프로그램 시작점(콘솔 UI). Controller 호출하고 결과 출력
  • Controller: 요청 처리 + 응답 포맷팅(ResponseDto) 담당
  • Service: 비즈니스 로직 + 트랜잭션(commit/rollback) 관리
  • DAO: JDBC(SQL 실행)만 담당. Connection은 외부(Service)에서 주입받음
  • DTO: 계층 간 데이터 전달용 객체
  • DBUtil: DB 연결 설정/생성 담당

호출 흐름

[요청]

View → Controller → Service → Dao → DB

 

[응답]
Dao 결과 → Service 가공/트랜잭션 종료 → Controller가 ResponseDto로 포장 → View 출력


3. 왜 레이어를 나눴나?

(1) 관심사 분리(Separation of Concerns)

  • SQL/JDBC 코드는 DAO에만
  • 트랜잭션/업무 흐름은 Service에만
  • 사용자가 볼 메시지/응답 형식은 Controller에만
  • 출력/실행은 View에만

즉, “한 파일에 다 넣으면” 수정이 어려워지는 문제를 방지.

(2) 변경에 강함

  • DB 쿼리 변경 → DAO만 수정
  • 트랜잭션 정책 변경 → Service만 수정
  • 응답 형식 변경 → Controller의 ResponseDto만 수정
  • 출력 방식 변경(콘솔 → 웹/REST) → View/Controller 중심으로 수정

4. 레이어별 책임 분석

View

  • UI 역할
  • Controller 호출 결과를 그대로 출력

특징:

  • View는 DB나 SQL을 전혀 모름
  • 어떤 일이 일어나는지를 모른 채 호출과 출력 반복

Controller

View와 Service 사이에서
입력과 출력을 각각 변환해주는 어댑터(중간 변환 계층) 역할을 한다.

입력 변환

사용자의 입력을 Service가 처리하기 쉬운 객체(DTO)로 변환

DeptDto dto = new DeptDto(deptno, dname, loc);
DeptService.insertDept(dto);

 

💡 Tip

객체화(DTO)가 반드시 Controller로 국한되는 것은 아니다. 때로는 Service에서 할 수도 있다.
Service에서 객체화를 선택할 만한 상황
1. 입력값 조합/가공이 업무 로직에 가깝게 붙어 있을 때
    - 예: 비밀번호 해싱, 기본값 세팅, 상태값 계산, 생성 규칙 적용 등
2. 요청 DTO와 DB DTO가 다른 모델이라 변환이 필요할 때
    - 요청은 {dname, loc}만 오고, Service에서 deptno 생성하는 케이스 등

 

출력 변환

Service의 처리 결과를 View가 출력하기 쉬운 형태(ResponseDto)로 감싸 전달 -> 응답의 표준화

deptList = DeptService.getAllDepts();
return ResponseDto.success("모든 부서 검색 성공", deptList);

Service

비즈니스 로직을 수행하는 가장 중요한 계층

  1. DB 연결 생성(DBUtil.getConnection())
  2. 여러 DAO 호출을 “하나의 업무 단위”로 묶음
  3. 트랜잭션 경계 설정: setAutoCommit(false) → commit/rollback
  4. DAO 결과를 boolean 등으로 해석해서 반환

트랜잭션 처리 위치가 Service인 이유

DAO는 “하나의 SQL 실행”만 담당하고,
Service는 “업무 흐름” 단위를 담당함.

업무 단위 예시:

  • 부서 생성(insert) + 로그 테이블 insert
  • 부서 삭제 + 관련 데이터 삭제

이런 경우를 대비하면 트랜잭션은 DAO가 아니라 Service가 잡아야 함.


예외 처리 방식

  • Service는 SQLException 발생시 rollback을 수행하고 다시 Exception을 던진다(throw)
  • 즉, Service는 예외를 해결하지 않고 정리(rollback) 후 위임한다

Service는 트랜잭션 자원을 책임지므로, 실패 시 rollback까지 수행한 뒤 예외를 상위로 던진다.

 

⚠️ 만약 코드를 조금 더 고도화해서 다양한 예외를 처리하게 된다면?

예외 종류 생성 위치 이유
SQLException DAO DB 기술 문제
DataAccessException Service 기술 예외를 비즈니스 의미로 변환
NotFoundException Service 비즈니스 규칙 판단
ValidationException Service 또는 Controller 입력 검증 위치에 따라 다름

 

❓ DataAccessException 은 뭘까

지금까지 catch 절에서 자주 활용했던 SQLException은 약간의 단점을 갖고 있다.

  1. 너무 기술적
  2. DB 밴더마다 다름
  3. 내부 정보 중심

이런 지루하고 현학적인 기술 예외를 Controller 까지 올려서 처리하게 되면 피곤해진다.

이걸 처리할 수 있다는 것은 Controller가 DB 구조를 알고있어야 한다는 뜻이기도 하다 -> 계층 간 결합도 증가

또 메시지가 그대로 사용자에게 노출되는 것도 좋지 않다.

 

그래서 DataAccessException은 무엇이냐

목적 1. 기술 예외를 숨기기(추상화)

SQLException (DB 기술 예외)
        ↓
DataAccessException (의미 중심 예외)

상위 레이어에서는 "데이터 접근 중 오류가 발생했습니다" 정도만 확인할 수 있으면 적당하다.

 

목적 2. 계층 간 결합도 낮추기

아래 코드처럼 Controller가 SQLException을 처리하는 것을 피해야 한다

catch (SQLException e) {
    if (e.getErrorCode() == 1062) { // MySQL duplicate key
        ...
    }
}

애초에 위의 Exception을 처리하려면 1062라는 에러코드를 알고 있어야 한다. 이런 구조를 계층붕괴라고한다.

그래서 코드를 조금 더 고도화 한다면 아래처럼 처리하는 것이 바람직하겠다.

DAO → SQLException
Service → DataAccessException으로 변환
Controller → 의미 기반 처리

DAO

  • Connection을 외부에서 주입받음
  • SQL 준비/실행
  • ResultSet → DeptDto 변환
  • 자원 해제는 try-with-resources로 자동 처리
  •  

DTO: Dto & ResponseDto

Dto

  • DB row를 담는 데이터 상자
  • 계층 간 전달을 위해 존재
  • 로직이 없고 데이터만 가짐

ResponseDto<T>

Controller의 출력 정책을 표준화
  • status: SUCCESS / FAIL / NOT_FOUND 등을 담을 수 있게 설계
  • msg: 사용자에게 보여줄 메시지
  • data: 실제 결과 데이터

콘솔에서 뿐만 아니라 REST API의 응답 포맷과 유사하다

{ 
  "status": "SUCCESS", 
  "msg": "...", 
  "data": {...} 
}

ResponseDto는 “응답을 일관되게 관리”하기 위한 DTO이며, View는 status/msg/data 규약만 알면 된다.

 

'Learning Log' 카테고리의 다른 글

[멋사 클라우드 5기] Day 17 - Flexbox  (0) 2026.02.13
[멋사 클라우드 5기] Day 16 - 브라우저의 동작 원리: 주소창에서 화면 렌더링까지  (0) 2026.02.12
[멋사 클라우드 5기] Day 14 - Modeling, JDBC 이해하기  (1) 2026.02.09
[멋사 클라우드 5기] Day 13 - DML, DDL, DCL, TCL  (0) 2026.02.08
[멋사 클라우드 5기] Day 12 - Join, Subquery, Union  (0) 2026.02.06
'Learning Log' 카테고리의 다른 글
  • [멋사 클라우드 5기] Day 17 - Flexbox
  • [멋사 클라우드 5기] Day 16 - 브라우저의 동작 원리: 주소창에서 화면 렌더링까지
  • [멋사 클라우드 5기] Day 14 - Modeling, JDBC 이해하기
  • [멋사 클라우드 5기] Day 13 - DML, DDL, DCL, TCL
allluck777
allluck777
allluck777
    • 분류 전체보기 (44) N
      • AWS (0)
      • Network (0)
      • Linux (0)
      • Docker (0)
      • Project (4)
        • CloudNote (4)
      • Learning Log (36) N
      • Lecture (3)
        • 스프링 입문 - 코드로 배우는 스프링 부트, 웹 .. (3)
  • 전체
    오늘
    어제
  • hELLO· Designed By정상우.v4.10.6
allluck777
[멋사 클라우드 5기] Day 15 - MVC & JDBC 구조 톺아보기
상단으로

티스토리툴바