3단계
3단계 — SQL 을 SSOT 로
30 분
3단계 — SQL 을 SSOT 로
JPA 자동 마이그레이션 (spring.jpa.hibernate.ddl-auto=update) 은 편하지만 위험해요. 운영 DB 의 컬럼 타입을 마음대로 바꾸거나 인덱스를 누락할 수 있어요. 우리는 SQL 파일 = 단일 진실 로 갑니다.
폴더 패턴
sql/
├── 001_create_users.sql
├── 002_create_posts.sql
├── 003_create_comments.sql
└── README.md
각 파일은 CREATE TABLE IF NOT EXISTS 로 멱등 — 몇 번 실행해도 안전.
-- sql/001_create_users.sql
CREATE TABLE IF NOT EXISTS users (
id BIGSERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_users_created_at ON users (created_at DESC);
DDL 실행 — 운영자만
이 SQL 들을 Spring 이 자동으로 돌리지 않게 합니다. application.yml:
spring:
jpa:
hibernate:
ddl-auto: validate # ← 자동 변경 X, 일치 확인만
대신 운영자가 직접 psql -f sql/001_create_users.sql 또는 admin UI 의 [DB 초기화] 버튼으로.
JPA 엔티티 — 읽기 전용으로 매핑
DDL 은 SQL 이 결정, 엔티티는 그 모양을 그대로 매핑만:
@Entity
@Table(name = "users")
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String email;
@Column(name = "password_hash", nullable = false)
private String passwordHash;
private Instant createdAt;
private Instant updatedAt;
}
엔티티가 새 컬럼을 추가 하는 게 아니라 SQL 이 추가한 컬럼을 읽어들이는 모양이에요.
직접 해 보기
sql/002_create_posts.sql 을 만들고 posts 테이블 (id, user_id FK, title, body, created_at) 을 정의해 보세요. JPA @Entity PostEntity 로 매핑하고 JpaRepository<PostEntity, Long> 인터페이스를 추가하면 CRUD 가 자동으로 됩니다.
더 깊이
다음 단계
4단계에서는 이 데이터를 외부에 노출하는 REST API 를 설계해요.