JPA란?
JPA란 Java에서 ‘객체 ↔ 관계 매핑(ORM)’을 지원하기 위한 표준 인터페이스이다.
JDBC와 달리 JPA는 데이터베이스와 상호작용하는 방법을 객체 지향적으로 추상화하여, 개발자가 객체를 중심으로 프로그래밍할 수 있도록 한다.
실제로 JPA는 인터페이스 모음에 불과하며, 구체적인 구현체인 Hibernate, EclipseLink, DataNuclues 등을 통하여 사용할 수 있다.
JPA 주요 개념
엔티티(Entity)
- 엔티티는 데이터베이스의 테이블과 매핑되는 Java 클래스이다. JPA는 엔티티 클래스를 통해 DB의 테이블 구조를 정의하고 매핑할 수 있다.
- 엔티티 클래스는 @Entity 와 같은 어노테이션을 통해 지정하며, 클래스 필드는 테이블의 각 컬럼에 매핑된다.
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity
public class User {
@Id
private Long id;
private String name;
private String email;
}
영속성 컨텍스트(Persistence Context)
- 영속성 컨테스트는 엔티티의 생명주기를 관리하는 일종의 캐시로, 특정 엔티티가 데이터베이스에서 조회된 상태를 유지하며, 엔티티의 변경을 자동으로 반영해 DB와 동기화 한다.
- JPA는 EntityManger를 통해 영속성 컨텍스트에 접근하여 엔티티를 저장, 수정, 삭제하는 작업을 수행한다.
엔티티 매니저(Entity Manager)
- 엔티티 매니저는 영속성 컨텍스트를 관리하는 객체로, JPA의 핵심 인터페이스이다. DB와의 모든 상호작용을 담당하며 엔티티의 작업을 수행한다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
User user = new User();
user.setName("Alice");
em.persist(user); // 영속성 컨텍스트에 User 엔티티 저장
em.getTransaction().commit();
em.close();
JPQL(Java Persistence Query Language)
- JPQL은 SQL과 유사한 문법을 가지면서 객체를 대상으로 하는 쿼리 언어이다. 기존에 SQL이 테이블을 대상으로 하는 것과 달리, JPQL은 엔티티를 대상으로 쿼리를 작성하며 객체와 DB 간의 간극을 줄인다.
- Java 클래스와 속성명을 기준으로 쿼리를 작성하게 된다.
List<User> users = em.createQuery("SELECT u FROM User u WHERE u.name = :name", User.class)
.setParameter("name", "Alice")
.getResultList();
JPA 주요 기능
1. CRUD 자동화
JPA는 기본적인 CRUD 작업을 쉽게 처리할 수 있도록 지원한다. 특히 JpaRepository 인터페이스를 통해 규칙에 맞게 인터페이스를 생성하면 쿼리를 작성하지 않아도 메서드 만으로 특정 엔티티를 조회할 수 있다.
2. 자동 변경 감지
JPA는 변경 감지 기능을 통해 영속성 컨텍스트에 있는 엔티티가 변경될 경우 자동으로 감지하여 데이터베이스에 반영한다.
3. 지연로딩(Lazy Loading)과 즉시 로딩(Eager Loading)
JPA는 지연로딩과 즉시로딩 전략을 통해 연관된 엔티티를 언제 로딩할지 결정할 수 있다.
- 지연로딩 : 연관 엔티티가 실제로 사용될 때 로딩하여 메모리 사용량을 줄이고 성능을 최적하한다.
- 즉시로딩 : 연관된 데이터를 한번에 로딩하여 객체 관계를 빠르게 조회한다.
4. 트랜잭션 관리
JPA는 DB의 트랜잭션을 관리하는 기능을 제공하며, Spring 의 경우 @Transactional 어노테이션을 통해 손쉽게 트랜잭션을 제어할 수 있다.
Spring 에서는 AOP 프록시가 @Transactional 어노테이션이 적용된 메서드를 호출할 때 트랜잭션을 호출하며 메서드가 종류될 때 트랜잭션을 종료한다. (AOP 형태로 동작하기 때문에 내부 메서드에 Transaction이 붙은 경우 하나의 트랜잭션으로 처리된다.)
JPA 장단점
장점
1. 생산성 향상
자동 CRUD 및 쿼리 메서드를 통해 직접적인 쿼리 작성 없이 메서드를 통해 개발할 수 있어 생산성이 높아진다.
2. 데이터베이스 독립성
JPA와 JPQL은 특정 데이터베이스에 의존하지 않으며 DB 변경에 코드 변경이 거의 없다.
3. 영속성 컨텍스트와 캐싱
영속성 컨텍스트를 통해 엔티티의 상태 변화를 자동으로 관리할 수 있다.
4. 트랜잭션 관리 및 자동화
@Transactional 어노테이션을 통해 트랜잭션을 자동으로 관리할 수 있어 편리하고 간결하다.
단점
1. 학습곡선
JPQL, 영속성 컨텍스트, 트랜잭션, Fetch 전략 등에 대한 학습이 필요하여 학습곡선이 높은 편이다. 특히 영속성 컨텍스트의 동작방식과 엔티티 생명주기를 이해하지 않으면 의도와 다른 결과를 낼 수 있다.
2. 성능 이슈
다음과 같은 성능 이슈 문제가 발생할 수 있다.
- N+1 문제 : 연관된 엔티티를 조회할 때 Lazy 전략을 사용하게 되면, 하나의 쿼리가 아니라 N+1개의 쿼리로 나뉘어 실행될 수 있다.
- 캐시 오버헤드 : 영속성 컨텍스트를 통한 캐싱을 하기 때문에 복잡한 연관관계를 가진 경우 성능에 부담이 될 수 있다.
- 추가 리소스 소비 : 지연 로딩 및 변경 감지 등의 기능은 추가적인 리소스를 소비하게 되어 대용량 데이터 처리 시 성능저하 문제가 발생할 수 있다.
3. 데이터베이스 고유 기능 제한
JPA는 DB 독립성을 유지하는 JPQL을 사용하기 때문에 DB의 특정 기능(MySQL의 LIMIT, Oracle의 ROWNUM 등)을 사용할 수 없다. 또한, 복잡한 쿼리를 작성하기에 어려울 수 있다
Hibernate
Hibernate는 JPA 인터페이스를 구현한 구현체로, JPA가 정의한 표준을 따르면서 다양한 추가 기능을 제공한다.
내부적으로 JPA 인터페이스를 구현하며 JDBC API를 통해 DB와 상호작용한다.
'공부 > Spring Boot' 카테고리의 다른 글
[Database] 04. MyBatis (1) | 2024.11.17 |
---|---|
[Database] 03. QueryDSL (1) | 2024.11.15 |
[Database] 01. JDBC (0) | 2024.11.13 |
[Spring Batch] 01. Spring Batch 기본 개념 (0) | 2024.11.13 |
[스프링 부트 공부 일지] 4. 웹 어플리케이션 서버 구축하기 (2) (0) | 2022.12.22 |