Post

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 호출
2JPA 인터페이스ORM 표준 API 제공, 규칙(스펙) 정의, 실제 동작을 구현체(Hibernate)에 위임
3Hibernate(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) 지정
@GeneratedValuePK 자동 생성 전략 지정 (IDENTITY, SEQUENCE, AUTO, TABLE)
@Column(name="컬럼명", nullable=..., length=...)필드와 DB 컬럼 매핑, 속성 설정 가능
@EmbeddedId복합 키(Composite Key)를 정의할 때 사용
@IdClass별도 클래스에 복합 키 정의

3. 연관 매핑

애너테이션설명
@OneToOne1:1 관계 매핑
@OneToMany1:N 관계 매핑
@ManyToOneN:1 관계 매핑
@ManyToManyN:N 관계 매핑
@JoinColumn(name="컬럼명")연관관계 컬럼 매핑
@JoinTableN:N 관계 매핑 시 조인 테이블 설정

4. 값 타임 매핑

애너테이션설명
@Embedded값 타입(Embeddable 객체) 매핑
@Embeddable값 타입 클래스 선언
@ElementCollection값 타입 컬렉션 매핑

5. 기타애너테이션

애너테이션설명
@Transient해당 필드를 DB 매핑에서 제외
@Version낙관적 락(Optimistic Lock)을 위한 버전 필드 지정
@LobCLOB/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.