Java | Spring

[Spring Boot] Bank App (2) 모델링, DB 설계

@leem 2025. 2. 17. 01:02

모델링

모델링이란?

모델링은 현실 세계의 개념을 컴퓨터 시스템에서 표현하는 과정이에요.
중요한 정보를 정리하고, 관계를 정의하면서 데이터 구조와 알고리즘을 설계하는 작업이에요.

특히, 데이터베이스 모델링은 정보 시스템의 데이터 구조를 설계하는 데 초점이 맞춰져 있어요.
그런데 DB의 데이터 타입과 자바의 데이터 타입은 완전히 같지 않아요.
그래서 DB의 개념을 자바에서 활용할 수 있도록 변환하는 과정이 필요합니다.


ORM (Object-Relational Mapping)

ORM은 객체와 관계형 데이터베이스를 매핑하는 기술이에요.
쉽게 말하면, SQL을 직접 작성하지 않고도 객체의 속성과 메서드를 활용해 데이터를 조작할 수 있는 방법이에요.

ORM을 사용하면 좋은 점

SQL을 직접 작성하지 않아도 돼서 코드가 간결해져요.
비즈니스 로직에 집중할 수 있어요.
데이터베이스 변경 시 유지보수가 쉬워요.

대표적인 ORM 기술

  • Java → Hibernate, MyBatis
  • Python → SQLAlchemy
  • Ruby → ActiveRecord

TRM (Table-Relational Mapping)

TRM은 테이블 간의 관계를 매핑하는 과정이에요.
우리가 흔히 말하는 1:1, 1:N, N:M 같은 관계를 설계하는 것을 의미해요.

테이블 간 관계 예시

  • 1:N 관계 → 한 명의 유저는 여러 개의 계좌를 가질 수 있음
  • N:M 관계 → 한 계좌를 여러 명이 공유할 수도 있음

테이블 간의 관계를 잘 정리해야, 나중에 데이터를 다룰 때 훨씬 수월해져요.


데이터베이스 테이블 설계

-- 데이터베이스 생성
CREATE DATABASE mybank;
USE mybank;

-- 유저 테이블
CREATE TABLE user_tb (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    password VARCHAR(100) NOT NULL,
    fullname VARCHAR(50) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- 계좌 테이블
CREATE TABLE account_tb (
    id INT AUTO_INCREMENT PRIMARY KEY,
    number VARCHAR(30) NOT NULL UNIQUE,
    password VARCHAR(30) NOT NULL,
    balance BIGINT NOT NULL COMMENT '계좌잔액',
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    user_id INT
);

-- 거래 내역 테이블
CREATE TABLE history_tb (
    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '거래내역 ID',
    amount BIGINT NOT NULL COMMENT '거래금액',
    w_account_id INT COMMENT '출금 계좌 ID',
    d_account_id INT COMMENT '입금 계좌 ID',
    w_balance BIGINT COMMENT '출금 후 잔액',
    d_balance BIGINT COMMENT '입금 후 잔액',
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

테이블을 자바 객체(Entity)로 변환

User.java (유저 모델)

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String username;
    private String password;
    private String fullname;
    private Timestamp createdAt;
}

 Account.java (계좌 모델)

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Account {
    private Integer id;
    private String number;
    private String password;
    private Long balance;
    private Integer userId;
    private Timestamp createdAt;
    
    // 출금 기능
    public void withdraw(Long amount) {
        this.balance -= amount;
    }

    // 입금 기능
    public void deposit(Long amount) {
        this.balance += amount;
    }
}

History.java (거래 내역 모델)

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class History {
    private Integer id;
    private Long amount;
    private Long wBalance;
    private Long dBalance;
    private Integer wAccountId;
    private Integer dAccountId;
    private Timestamp createdAt;
}

📌 DTO vs Entity 차이점

구분 DTO (Data Transfer Object) Entity (데이터 모델)
목적 데이터를 주고받기 위한 용도 DB 테이블과 직접 매핑
사용 위치 컨트롤러-서비스 간 데이터 전달 DB와 직접 연결
로직 포함 여부 ❌ 로직 없음 ✅ 비즈니스 로직 포함 가능
변경 가능 여부 불변 (Immutable) 상태 변경 가능
예시 UserDto, AccountDto User, Account

✔ DTO → 데이터를 주고받을 때 사용 (ex. API 응답)
✔ Entity → DB 테이블과 연결되는 객체 (ex. Hibernate, MyBatis에서 사용)


웹 요청이 처리되는 흐름

1️⃣ 정적 파일 요청 흐름 (CSS, JS, 이미지 파일 요청)

[웹 브라우저] → [Spring Boot 내장 웹서버] → [정적 파일 응답]
 

브라우저가 index.html이나 style.css 요청하면, Spring Boot가 바로 파일을 찾아서 반환해요.

2️⃣ 동적 요청 흐름 (JSP, JSON, DB 요청 등)

[웹 브라우저] → [웹 서버] → [WAS] → [Spring 컨트롤러] → [서비스 로직] → [DB] → [응답]

요청 흐름 예시

  1. 사용자가 /account 요청
  2. 컨트롤러가 요청을 받음
  3. 서비스 계층에서 로직 실행
  4. DB에서 데이터 가져와 응답
  5. 요청이 들어오면, 컨트롤러 → 서비스 → 리포지토리 → DB 순으로 처리됨

📌 서블릿 컨테이너

서블릿 컨테이너는 개발자가 웹 서버와 통신하기 위해 소켓을 생성하고, 특정 포트에 리스닝하고, 스트림을 생성하는 등의 복잡한 작업을 하지 않아도 되도록 해주는 역할을 함.

서블릿 컨테이너의 역할

✔ 서블릿의 생성부터 소멸까지의 생명주기(life-cycle)를 관리
✔ 요청이 들어올 때마다 새로운 스레드를 생성하여 개별 요청을 처리
JSP & 서블릿 실행 환경 제공

→ 서블릿 컨테이너는 클라이언트의 HTTP 요청을 받아들이고, 서블릿 및 JSP를 실행하는 환경을 제공하는 소프트웨어임.


모델링이란? 데이터를 체계적으로 정리하는 과정
ORM vs TRM → ORM은 객체-테이블 매핑, TRM은 테이블 간 관계 매핑
DB 테이블 설계 & 자바 모델 변환
DTO와 Entity 차이점 정리
웹 요청 흐름 정리
서블릿 컨테이너의 역할