- [JPA] 1. Java Persistence API 들어가기2025년 01월 05일 10시 43분 48초에 업로드 된 글입니다.작성자: nickhealthy
애플리케이션에서 데이터베이스를 관리하는 여러 방법
애플리케이션에서 관계형 데이터베이스를 관리하는 방법은 여러가지가 있다. 우선 JPA를 학습하기 전, 다음과 같은 방법들을 직접 코드를 통해 비교해보고 JPA를 사용하면 어떤 이점과 단점이 있는지 확인해보자.
1. JDBC (Java Database Connectivity)
JDBC는 Java 애플리케이션과 관계형 데이터베이스 사이의 연결을 관리하는 표준 API이다. SQL 작성부터 파라미터 바인딩, 심지어 커넥션 연결/해제, 트랜잭션 처리 등 하나의 SQL 문을 처리하기 위한 여러 코드 작성이 필요하다.
- 특징: 직접적인 `Connection`, `PreparedStatement`, `ResultSet` 객체를 사용하여 데이터베이스와 상호작용한다.
- 단점: 코드가 반복적이고, 연결 및 예외 처리 등을 개발자가 직접 관리해야 한다.
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class JdbcExample { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/mydb"; String username = "root"; String password = "password"; try (Connection conn = DriverManager.getConnection(url, username, password)) { String sql = "SELECT id, name FROM users"; try (PreparedStatement stmt = conn.prepareStatement(sql); ResultSet rs = stmt.executeQuery()) { while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); System.out.println("ID: " + id + ", Name: " + name); } } } catch (SQLException e) { e.printStackTrace(); } } }
2. SQL Mapper
JDBCTemplate, MyBatis 등 SQLMapper 기술을 통해 코드가 순수 JDBC를 사용하는 것 보단 확연히 줄어들었지만, 여전히 SQL를 작성해야 하는 번거로움은 남아있다.
- 특징: 데이터베이스와의 연결 및 리소스 관리, 예외 처리를 자동으로 처리한다. 코드가 더 간결하고, 리소스 관리가 쉬워진다.
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; import javax.sql.DataSource; import java.util.List; public class JdbcTemplateExample { public static void main(String[] args) { // DataSource 설정 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mydb"); dataSource.setUsername("root"); dataSource.setPassword("password"); // JdbcTemplate 객체 생성 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); // SQL 쿼리 실행 String sql = "SELECT id, name FROM users"; List<User> users = jdbcTemplate.query(sql, (rs, rowNum) -> { int id = rs.getInt("id"); String name = rs.getString("name"); return new User(id, name); }); // 결과 출력 for (User user : users) { System.out.println("ID: " + user.getId() + ", Name: " + user.getName()); } } } class User { private int id; private String name; public User(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public String getName() { return name; } }
3. JPA
아래와 같이 JPA를 사용하게 되면 SQL를 작성해야 할 필요도 없고, 마치 컬렉션을 저장하고 조회하는 것처럼 코드를 작성하면 된다.
- 특징: 객체와 데이터베이스 테이블 간의 매핑을 통해 SQL을 직접 작성하지 않고도 데이터를 조회하고 수정할 수 있다. JPQL(Java Persistence Query Language)을 사용해 객체 지향적으로 데이터를 다룬다.
- 단점: JPA 설정이 비교적 복잡할 수 있고, 초기 설정이 필요하다. 또한, SQL 쿼리 성능 최적화가 어려운 경우도 있다.
import javax.persistence.*; import java.util.List; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; // Getters and setters public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class JpaExample { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPAUnit"); EntityManager em = emf.createEntityManager(); // JPA에서 쿼리 실행 String jpql = "SELECT u FROM User u"; TypedQuery<User> query = em.createQuery(jpql, User.class); List<User> users = query.getResultList(); // 결과 출력 for (User user : users) { System.out.println("ID: " + user.getId() + ", Name: " + user.getName()); } em.close(); emf.close(); } }
JPA 적용 사례 및 향후 동향
- 우아한형제들, 쿠팡, 카카오, 네이버 등 적용
- 조 단위의 거래금액이 발생하는 다양한 서비스에서 사용, 검증
- 최근 5년 동안 동향을 살펴보아도 2022년 이후부터 JPA가 더 많은 관심을 받고 있는 것을 알 수 있다.
구글 트렌드 JPA(Java Persistence API)란 무엇인가?
자바 애플리케이션에서 객체와 관계형 데이터베이스 간의 상호작용을 매핑하고 관리할 수 있도록 지원하는 자바 표준 API이다. JPA의 핵심 목적은 관계형 데이터베이스에서 데이터를 저장하고 조회하는 작업을 객체지향적으로 수행할 수 있게 하는 것이다. 이로 인해, 데이터베이스와의 직접적인 상호작용을 최소화하고 개발자가 더 쉽게 데이터베이스와 작업할 수 있도록 도와준다.
JPA의 주요기능
- 객체-관계 매핑 (ORM, Object-Relational Mapping): 자바 객체와 데이터베이스 테이블 간의 매핑을 지원한다. 이를 통해 데이터베이스의 레코드를 자바 객체로 변환하고, 자바 객체를 다시 데이터베이스에 저장하는 작업을 쉽게 처리할 수 있다.
- 자동화된 CRUD: 기본적인 CRUD(Create, Read, Update, Delete) 작업을 코드로 간편하게 처리할 수 있다.
- 트랜잭션 관리: JPA는 트랜잭션을 관리하고, 데이터베이스 작업의 일관성을 유지하는 데 필요한 기능을 제공한다.
- 쿼리 언어 (JPQL): JPA는 SQL과 비슷하지만 자바 객체를 대상으로 하는 JPQL(Java Persistence Query Language)이라는 쿼리 언어를 제공한다. 이를 통해 객체지향적인 방식으로 데이터베이스 쿼리를 작성할 수 있다.
JPA의 핵심 구성 요소
JPA는 크게 3가지 핵심 구성 요소로 이루어져 있다.
- Entity: 데이터베이스 테이블과 매핑되는 자바 클래스를 뜻한다. `@Entity` 어노테이션을 사용해 해당 클래스를 엔티티로 정의한다. 각 인스턴스는 데이터베이스의 레코드와 일대일로 매핑된다.
- Entity Manager: 엔티티 객체를 저장하고 조회하는 주요 인터페이스. EntityManager는 CRUD 작업과 JPQL 쿼리 실행 등을 담당한다.
- Persistence Context: 엔티티 객체는 영속성 컨텍스트(Persistence Context)라는 메모리 영역에 존재한다. 이 영역은 엔티티의 상태를 관리하고, 변경 사항을 데이터베이스에 반영한다. (다음 포스팅에 자세히 작성 예정)
JPA의 주요 어노테이션
JPA에서는 다양한 어노테이션을 사용하여 객체와 데이터베이스 간의 매핑을 설정한다. 대표적인 어노테이션은 다음과 같다.
- @Entity: 해당 클래스가 JPA 엔티티임을 선언
- @Id: 엔티티의 기본 키를 정의
- @GeneratedValue: 기본 키 값의 생성 전략을 지정
- @Column: 클래스 필드와 데이터베이스 컬럼 간의 매핑을 정의
- @OneToMany, @ManyToOne, @OneToOne: 엔티티 간의 관계를 설정
- @ManyToMany: 다대다 관계를 설정
JPA의 장점
- 객체지향적 접근: JPA는 관계형 데이터베이스를 객체지향적으로 다룰 수 있게 해주므로, 자바 객체와 관계형 데이터베이스 간의 매핑을 쉽게 할 수 있다.
- SQL과 분리된 쿼리: JPQL을 사용하면 SQL에 의존하지 않고 객체 지향적인 방식으로 쿼리를 작성할 수 있다.
- 트랜잭션 관리의 용이성: JPA는 트랜잭션 관리 기능을 내장하고 있어, 트랜잭션을 쉽게 처리하고 롤백할 수 있다.
- 자동화된 CRUD: 기본적인 CRUD 작업을 EntityManager를 통해 자동으로 처리할 수 있어, 개발자가 반복적인 작업에 시간을 낭비하지 않아도 된다.
JPA의 단점
- 학습량: JPA는 처음 사용할 때 학습해야 할 개념들이 많다. 특히, 영속성 컨텍스트, 지연 로딩, 트랜잭션 등의 개념을 이해하는 데 시간이 필요하다.
- 성능 문제와 SQL 최적화: 복잡한 쿼리나 큰 데이터셋을 처리할 때 성능 저하가 발생할 수 있다. JPA는 SQL을 추상화하기 때문에, 성능 최적화가 어려울 수 있다. 하지만 Query DSL 라이브러리로 이와 같은 문제를 해결한다고 한다.
JPA 주요 동작 방식
JPA 구동 방식
- 설정 정보를 읽는다.
- 설정 정보를 기반으로 `EntityManagerFactory`를 생성한다
- EntityManagerFactory는 하나만 애플리케이션 전체에서 공유한다.
- EntityManagerFactory를 통해서 생성된 `EntityManager`는 사용할 때마다 새로 생성해서 사용한다.
- 쓰레드 간에 공유하거나 재사용하면 안된다.
이미지1 이미지2 JPA는 애플리케이션과 JDBC 사이에서 동작
JPA는 마치 JDBCTemplate, MyBatis 처럼 JDBC API를 사용해 중간에서 객체 또는 SQL 문으로 변환하고, 데이터베이스와 통신한다.
JPA 동작 - 저장
JPA에서 관리하는 데이터를 `Entity`라고 하는데, 아래 그림처럼 Repository 계층에서 데이터를 저장하면, JPA는 Entity의 명세를 분석하여 INSERT 쿼리를 생성한다. 트랜잭션도 자동으로 처리된다. 여기서 중요한 점은 객체와 관계형 데이터베이스 간의 패러다임 불일치를 JPA가 자동으로 해결해 준다는 것이다.
JPA 동작 - 조회
자바 애플리케이션에서 객체를 조회할 때는 마치 자바 컬렉션(List, Map 등)에서 조회하는 것처럼 코드를 작성하면, JPA에서 이를 SELECT 문으로 자동 변환하고, DB에서 조회된 데이터를 객체로 변환하여 가져온다.
다음글이 없습니다.이전글이 없습니다.댓글