Spring

JPA (Java Persistence API)란?

0and24 2024. 12. 10. 16:35

https://www.turing.com/kb/jpa-for-database-access

JPA(Java Persistence API)는 Java 개발자가 데이터베이스 작업을 객체 지향적으로 처리할 수 있도록 지원하는 표준 사양입니다. SQL을 직접 작성하는 대신, 데이터베이스 테이블과 자바 객체(Entity)를 매핑하여 작업할 수 있도록 돕습니다. JPA는 인터페이스를 정의한 스펙이며, Hibernate, EclipseLink 등 다양한 구현체가 존재합니다.

1. JPA의 핵심 개념

(1) ORM (Object-Relational Mapping)

  • 객체와 관계형 데이터베이스를 자동으로 매핑합니다.
  • SQL 중심이 아닌, 엔티티 객체 중심으로 데이터를 다룹니다.

(2) Entity

  • 데이터베이스 테이블과 매핑되는 클래스입니다.
  • 예: @Entity 어노테이션을 통해 매핑 선언.
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String email;
}

(3) JPQL (Java Persistence Query Language)

  • JPA에서 제공하는 객체 지향 SQL입니다.
  • 데이터베이스의 테이블이 아닌 엔티티 객체를 대상으로 쿼리 작성.
@Query("SELECT u FROM User u WHERE u.name = :name")
List<User> findByName(@Param("name") String name);

(4) 영속성 컨텍스트 (Persistence Context) ⭐

  • 엔티티 객체를 1차 캐시에 저장하고 관리하여 같은 객체를 여러 번 조회할 때 동일한 객체를 반환합니다.
  • 트랜잭션과 연계되어 변경 내용을 자동으로 감지(Dirty Checking)하여 업데이트 쿼리를 생성합니다.
 

2. JPA의 주요 특징

(1) 생산성 향상

  • SQL을 직접 작성하지 않고, 객체 기반으로 데이터 처리가 가능.
  • 데이터베이스 작업 코드가 간결해지고 유지보수성이 증가.

(2) 데이터 변경 감지 (Dirty Checking)

  • 엔티티 객체의 상태 변화를 자동으로 감지하고, 변경 사항을 데이터베이스에 반영합니다.

(3) 지연 로딩 (Lazy Loading) 및 즉시 로딩 (Eager Loading)

  • 연관된 데이터 로딩 방식을 설정하여 성능 최적화 가능.

(4) 트랜잭션 관리

  • 데이터 변경 작업은 트랜잭션 안에서 처리되며, 변경 사항은 commit 시점에 반영됩니다.

3. JPA의 장점

(1) SQL 작성 부담 감소

  • CRUD 작업을 위한 SQL 쿼리를 작성하지 않아도 됩니다.
  • Repository 인터페이스를 사용하여 기본적인 데이터 조작이 가능.

(2) 생산성과 유지보수성 증가

  • 객체 중심 개발로 코드 가독성과 유지보수성이 향상.
  • 데이터베이스 변경에도 엔티티 수정만으로 쉽게 대처 가능.

(3) 캐싱 기능

  • 1차 캐시를 통해 데이터베이스 호출 횟수를 줄여 성능을 향상.

(4) 데이터베이스 독립성

  • 데이터베이스에 종속되지 않고, 다양한 데이터베이스와 호환 가능.

4. JPA의 단점

(1) 학습 곡선

  • ORM과 JPA의 개념 및 동작 방식을 익히는 데 시간이 필요합니다.

(2) 초기 설정 복잡

  • persistence.xml이나 Spring Boot 설정 등 초기 설정 작업이 필요.

(3) 복잡한 쿼리 처리 어려움

  • JPQL이나 Criteria API로 해결할 수 없는 복잡한 SQL 쿼리는 Native Query를 사용해야 합니다.

(4) 성능 튜닝 필요

  • 잘못된 매핑, 연관 관계 설정 등으로 인해 성능 문제가 발생할 수 있어 성능 최적화에 신경 써야 합니다.

 

JPA를 사용한 기본적인 CRUD 문법을 보면 매우 간단한 것을 볼 수 있습니다.

// CREATE
User user = new User();
user.setName("John");
user.setEmail("john@example.com");
entityManager.persist(user);

// READ
User foundUser = entityManager.find(User.class, 1L);

// UPDATE
foundUser.setName("John Doe");
entityManager.merge(foundUser);

// DELETE
entityManager.remove(foundUser);

아래는 Spring Data JPA 사용시

public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByName(String name);
}

6. 제가 JPA를 공부하고 있는 이유

과거에는 MyBatis를 사용해 SQL을 직접 작성하며 데이터를 조작했지만, 프로젝트가 커질수록 다음과 같은 문제가 발생했습니다:

  1. SQL 중심 개발의 비효율성: 테이블 스키마가 변경되면, 관련된 SQL을 모두 수정해야 했습니다.
  2. 코드의 중복 증가: 여러 Mapper에서 유사한 SQL 코드가 반복되었습니다.
  3. 유지보수 어려움: 복잡한 쿼리가 비즈니스 로직과 뒤섞여 가독성이 낮아졌습니다.

JPA는 객체 중심 개발을 지원하여 이러한 문제를 해결했습니다.

  • 데이터베이스 스키마가 변경되어도 엔티티 클래스를 수정하면 대부분 자동 반영됩니다.
  • Dirty Checking을 통해 변경 사항을 자동으로 감지하므로, 코드 중복이 줄어듭니다.
  • JPQL을 활용하면 SQL에 비해 가독성이 높은 쿼리를 작성할 수 있습니다.

물론, MyBatis와 JPA는 상호 배타적인 관계가 아닙니다. 상황에 따라 MyBatis의 강력한 Native SQL 처리 기능JPA의 객체 지향적 데이터 관리를 병행해 사용할 수도 있습니다. 제가 JPA를 깊이 공부하려는 이유는 이러한 기술들이 어떤 상황에서 적합한지 판단하려면, 각각의 특징과 장단점을 명확히 이해해야 한다고 생각하기 때문입니다. 특히 이론적인 부분을 학습함으로써 실제 사용할 때 더 좋은 선택을 할 수 있을 것이라 생각합니다.

 

참고 자료:
https://www.turing.com/kb/jpa-for-database-access

 

What is Java Persistence API (JPA) for Database Access

Understanding what is JPA and how to configure and use Hibernate with different methods.

www.turing.com