05 JPA
05 JPA
2025.10.04. 일단 스프링부트 이해를 위한 대략적인 흐름만 파악, DB에 관한 상세한 내용은 스프링부트 흐름 파악하고 공부!
1. JPA
1. JPA(Java Persistence API)
- 자바 진영에서 “객체 ↔ 관계형 데이터베이스 매핑(ORM)”을 표준으로 정의해둔 인터페이스 규칙
2. JPA의 핵심기능
- 엔티티 매핑: 자바 객체 ↔ DB 테이블 자동 매핑 (@Entity, @Table, @Id 등)
- 쿼리 자동 생성: CRUD 쿼리를 객체 중심으로 작성 가능 (em.persist(), em.find())
- 캐싱: 1차 캐시/쓰기 지연/더티 체킹 → SQL 최소화
- JPQL: SQL 비슷한 객체 쿼리 언어 제공 ㅊ
2. JPA - 하이버네이트 - 영속성 컨텍스트
1. 하이버네이트
- 자바 객체 중심으로 DB를 다룰 수 있게 해주는 ORM 프레임워크
- JPA 표준 구현체
특징
구분 특징 설명 쿼리 언어 HQL/JPQL 지원 객체 중심 쿼리 언어 사용, SQL 직접 작성 최소화 캐싱 1차/2차 캐시 동일 트랜잭션 내 중복 쿼리 방지(1차), 전역/분산 캐시 지원(2차) 지연 로딩 Lazy Loading 실제 접근할 때 쿼리를 실행, 불필요한 데이터 로딩 방지 더티 체킹 Dirty Checking 엔티티 객체 값이 변경되었는지 자동으로 감지해서, 변경된 부분만 DB에 업데이트하는 기능 DB 호환성 Dialect 제공 Oracle, MySQL, PostgreSQL 등 다양한 DB 지원 고급 매핑 상속/연관관계 매핑 상속 매핑, 1:1, 1:N, N:N, 복합 키 매핑 등 다양한 매핑 전략 Native SQL 직접 SQL 실행 가능 ORM 외에도 필요시 SQL 직접 실행 지원
2. 영속성 컨텍스트
- JPA에서 관리하는 엔티티 객체의 저장소(캐시)
- Hibernate에서는 Session, JPA 표준에서는 EntityManager 안에서 관리
특징
특징 설명 1차 캐시 같은 트랜잭션 안에서 조회한 엔티티를 메모리에 저장 → 동일 엔티티 재조회 시 DB 접근 없이 캐시에서 반환 엔티티 생명주기 관리 엔티티 상태(Transient, Persistent, Detached, Removed)를 관리 변경 감지(Dirty Checking) 트랜잭션 커밋 시점에 엔티티의 변경 여부를 자동 검사하고 DB 반영 동일성 보장 같은 엔티티를 조회하면 항상 동일한 인스턴스 반환 트랜잭션 범위 유지 영속성 컨텍스트는 EntityManager(Session) 생명주기 동안 유지되며, 트랜잭션 종료 시 초기화 쓰기 지연(Write-Behind) 변경된 엔티티를 모아서 트랜잭션 커밋 시점에 DB에 반영 지연 로딩(Lazy Loading) 지원 실제 데이터 접근 시점까지 연관 엔티티 조회를 지연 처리 가능
3. 흐름
순서 | 구성 요소 | 역할 |
---|---|---|
1 | 개발자 코드 | @Entity , @Id 등으로 엔티티 정의, EntityManager 또는 Repository 호출 |
2 | JPA 인터페이스 | ORM 표준 API 제공, 규칙(스펙) 정의, 실제 동작을 구현체(Hibernate)에 위임 |
3 | Hibernate(ORM) | JPA 구현체, SQL 생성, 영속성 컨텍스트 관리, 캐싱, Dirty Checking 수행 |
4 | 영속성 컨텍스트 | Hibernate 내부 메모리 공간, 엔티티 상태 관리, 1차 캐시 제공 |
5 | 데이터베이스(DB) | 실제 데이터 저장소, Hibernate가 생성한 SQL 실행, 데이터 CRUD 처리 |
2. JPA 사용
1. 흐름
단계 | 역할 |
---|---|
엔티티(Entity) 정의 | DB 테이블 구조를 자바 클래스로 매핑 (@Entity , @Table , @Id , @Column 등 사용) |
레파지토리(Repository) 정의 | 엔티티에 대한 CRUD, 쿼리 메서드 정의 (JpaRepository , CrudRepository 상속) |
서비스(Service) | 레파지토리 호출 → 비즈니스 로직 처리 |
컨트롤러(Controller) | 서비스 호출 → 결과 반환(웹 API / 화면 렌더링) |
3. 엔티티 정의하기
1. 애너테이션
1. 엔티티선언
애너테이션 | 설명 |
---|---|
@Entity | 해당 클래스가 JPA 엔티티임을 선언 |
@Table(name="테이블명") | 엔티티와 매핑할 DB 테이블 이름 지정 (생략 시 클래스명이 테이블명으로 사용) |
2. 기본키
애너테이션 | 설명 |
---|---|
@Id | 엔티티의 기본 키(PK) 지정 |
@GeneratedValue | PK 자동 생성 전략 지정 (IDENTITY , SEQUENCE , AUTO , TABLE ) |
@Column(name="컬럼명", nullable=..., length=...) | 필드와 DB 컬럼 매핑, 속성 설정 가능 |
@EmbeddedId | 복합 키(Composite Key)를 정의할 때 사용 |
@IdClass | 별도 클래스에 복합 키 정의 |
3. 연관 매핑
애너테이션 | 설명 |
---|---|
@OneToOne | 1:1 관계 매핑 |
@OneToMany | 1:N 관계 매핑 |
@ManyToOne | N:1 관계 매핑 |
@ManyToMany | N:N 관계 매핑 |
@JoinColumn(name="컬럼명") | 연관관계 컬럼 매핑 |
@JoinTable | N:N 관계 매핑 시 조인 테이블 설정 |
4. 값 타임 매핑
애너테이션 | 설명 |
---|---|
@Embedded | 값 타입(Embeddable 객체) 매핑 |
@Embeddable | 값 타입 클래스 선언 |
@ElementCollection | 값 타입 컬렉션 매핑 |
5. 기타애너테이션
애너테이션 | 설명 |
---|---|
@Transient | 해당 필드를 DB 매핑에서 제외 |
@Version | 낙관적 락(Optimistic Lock)을 위한 버전 필드 지정 |
@Lob | CLOB/BLOB 타입 매핑 |
@Basic(fetch = FetchType.LAZY) | 기본 속성의 지연 로딩 지정 |
2. 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long number;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private Integer price;
@Column(nullable = false)
private Integer stock;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
4. 레파지토리
1. 레파지토리
- 엔티티(Entity)를 DB에서 조회, 저장, 수정, 삭제(CRUD) 하는 계층
2. 생성
1
2
3
4
public interface 엔티티명Repository extends JpaRepository<엔티티명, ID타입> {
// 엔티티명 : 엔티티 클래스명 => Product
// ID타입 : 엔티티의 기본 키 타입(@Id 타입) => Long → User
}
3. CRUD
- JpaRepository를 상속하면 기본적으로 다음 기능이 자동 생성
생성 CRUD
작업 JpaRepository 메서드 설명 생성(Create) save(entity)
새로운 엔티티 저장, 이미 존재하는 엔티티면 수정 조회(Read) findById(id)
ID로 단일 엔티티 조회 → Optional 반환 findAll()
전체 엔티티 조회 → List 반환 findAllById(ids)
여러 ID로 조회 커스텀 메서드 findBy필드명(value)
형태로 자동 생성 가능수정(Update) save(entity)
기존 엔티티 수정 시 사용 (PK 기준으로 업데이트) 삭제(Delete) delete(entity)
엔티티 객체 삭제 deleteById(id)
ID 기준 삭제 deleteAll()
전체 삭제 기타 count()
전체 엔티티 개수 조회 existsById(id)
ID 존재 여부 조회
4. 생성
1
2
3
4
5
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByName(String name); // name으로 조회
List<User> findByEmail(String email); // email로 조회
List<User> findByAgeGreaterThan(int age); // age가 특정 값 이상인 엔티티 조회
}
- PK설정(엔티티에서 @ID)한 것은 자동으로 CRUD가 생성.
- 그외에는 별도로 생성이 필요함.
This post is licensed under CC BY 4.0 by the author.