지금까지 SQL을 직접 써서 DB에 데이터를 넣었습니다. Java 코드에서 SQL을 쓰면 이런 모습입니다:
// JDBC로 직접 SQL 작성 (옛날 방식)
public Post findById(Long id) {
String sql = "SELECT id, title, content, author, created_at, updated_at FROM post WHERE id = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setLong(1, id);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
Post post = new Post();
post.setId(rs.getLong("id"));
post.setTitle(rs.getString("title"));
post.setContent(rs.getString("content"));
post.setAuthor(rs.getString("author"));
// ... 필드가 많으면 이 작업이 끝없이 반복
return post;
}
return null;
}
문제점이 명확합니다. SQL을 직접 쓰고, ResultSet에서 값을 하나씩 꺼내서 Java 객체에 넣어야 합니다. 테이블이 10개면 이런 코드가 수십 개 생깁니다.
Java 객체 (Post) ←→ ORM ←→ DB 테이블 (post)
───────────── ─────────────────
id (Long) ←→ id (BIGINT)
title (String) ←→ title (VARCHAR)
content (String) ←→ content (TEXT)
createdAt (LocalDateTime) ←→ created_at (DATETIME)
ORM을 쓰면:
// JPA 방식 (ORM)
Post post = postRepository.findById(1L).orElseThrow();
// 끝. SQL 없음. 매핑 코드 없음.
혼동하기 쉬운 개념입니다
JPA (Java Persistence API): 자바 ORM 기술의 표준 인터페이스(스펙)입니다. "이런 기능이 있어야 한다"는 규칙만 정의합니다. 실제 구현은 없습니다.
Hibernate: JPA 스펙을 실제로 구현한 라이브러리입니다. JPA의 구현체 중 가장 유명하고 널리 쓰입니다.
Spring Data JPA: Hibernate 위에 한 번 더 추상화한 스프링 모듈입니다. Repository 인터페이스만 만들면 구현체를 자동으로 생성해줍니다.
Spring Data JPA ← 우리가 직접 사용하는 계층
↓
Hibernate (JPA 구현체) ← 내부적으로 동작
↓
JDBC ← DB 연결
↓
MySQL ← 실제 DB
우리는 Spring Data JPA를 사용합니다. 직접 Hibernate를 다룰 일은 거의 없습니다.
JPA의 가장 핵심 개념입니다. 이걸 이해해야 나중에 발생하는 다양한 문제를 해결할 수 있습니다.
영속성 컨텍스트는 Entity를 관리하는 가상의 공간입니다. JPA는 Entity를 DB에 바로 저장하지 않고, 영속성 컨텍스트라는 중간 단계를 거칩니다.