JPA, Hibernate, Spring Data JPA, JDBC

wlsh44·2023년 1월 15일
0

jpa

목록 보기
1/1

JPA(Java Persistence API)

JPA는 Java Persistence API의 약자로 기술 명세, 즉 자바 표준 ORM 인터페이스입니다.

JPA는 크게 세 가지 기능을 제공합니다.

  • persistence API
    • entityManager 를 통해 JPA 핵심 인터페이스를 제공합니다.
  • 메타데이터
    • 엔티티를 생성할 때 사용하는 @Entity, @Id, @ManyToOne 등이 메타데이터에 해당됩니다.
  • JPQL(Java Persistence Query Language)

Spring Data JPA

스프링에서 제공하는 JPA를 더 쉽게 사용할 수 있게 하는 모듈입니다.
Spring Data JPA는 너무 많은 boilerplate 코드를 작성하는데 드는 고생을 줄이고 쉽게 data access layer에 접근할 수 있도록 함을 목적으로 만들어졌습니다.

Spring Data JPA docs 내용
Too much boilerplate code has to be written to execute simple queries as well as perform pagination, and auditing. Spring Data JPA aims to significantly improve the implementation of data access layers by reducing the effort to the amount that’s actually needed.

즉, 간단한 Repository 인터페이스를 만들 때 상속받는 JpaRepository가 바로 Spring Data JPA의 기술입니다.

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
}

Hibernate

Hibernate는 기술 명세인 JPA를 구현한 구현체입니다. 앞서 언급했듯이, JPA는 API, 인터페이스입니다. 따라서 JPA를 사용하기 위해서는 JPA가 요구하는 기능들을 실제로 구현한 구현체가 필요하고, 이 구현체들 중 가장 대표적인게 바로 Hibernate입니다. 그렇기 때문에 Hibernate와 JPA를 혼동하는 사람이 많은 것 같습니다.

위 사진들은 Hibernate가 어떻게 JPA를 구현하고 있는지를 보여줍니다. JPA에서 봤던 EntityManager를 Hibernate는 Session을 통해 구현하고 있는 것을 볼 수 있죠.

Hibernate는 JPA의 구현체이기 때문에 JPA를 사용하기 위해 반드시 Hibernate를 고집할 필요는 없습니다.
EclipseLink, DataNucleus 등 다른 JPA의 구현체를 사용해도 무방하나, Hibernate가 가장 대중적이고 성숙한 커뮤니티를 가졌다고 합니다.

이 사진이 JPA, Spring Data JPA, Hibernate의 차이를 가장 쉽게 보여주는 것 같습니다.

JDBC(Java Database Connectivity)

자바와 DB를 연결하기 위한 가장 낮은 단계의 표준 인터페이스입니다.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;

public class JdbcTest {
		@Test
		void test() throws Exception {
		    String driver = "org.h2.Driver";
		    String url = "jdbc:h2:mem:testdb";
		    String sql = "select * from member";
		
		    Connection con = null;
		    PreparedStatement pstmt = null;
		    ResultSet resultSet = null;
		
		    try {
		        Class.forName(driver);
		        con = DriverManager.getConnection(url, "sa", "");
		        pstmt = con.prepareStatement(sql);
		        resultSet = pstmt.executeQuery();
		
		        while (resultSet.next()) {
		            System.out.println("resultSet.getInt(1) = " + resultSet.getInt(1));
		            System.out.println("resultSet.getString(2) = " + resultSet.getString(2));
		        }
		    } catch (SQLException | ClassNotFoundException exception) {
		        exception.printStackTrace();
		    } finally {
		        try { Objects.requireNonNull(resultSet).close();} catch (SQLException ex) { ex.printStackTrace(); }
		        try { Objects.requireNonNull(pstmt).close();} catch (SQLException ex) { ex.printStackTrace(); }
		        try { Objects.requireNonNull(con).close();} catch (SQLException ex) { ex.printStackTrace(); }
		    }
		}
}

기본 JDBC를 이용해 DB에 접근하는 코드입니다.
동작 원리는 다음과 같습니다.

  • DriverManager를 통해 Driver 선택 → 커넥션 생성 → SQL생성 → 쿼리 실행 → ResultSet으로 결과 받음

하지만 예제 코드만 봐도 알 수 있듯이 JDBC는 많은 단점을 가지고 있습니다.
우선 Connection, Statement, ResultSet 모두 close를 시켜줘야 메모리 누수가 생기지 않습니다. 그렇게 하기 위해 try/catch를 이중으로 사용해야 하고, 리팩터링을 하는데 많은 힘이 들게 됩니다. 또한 가독성도 매우 떨어지는 것을 볼 수 있죠.
단순 select 쿼리 작성하는데도 대략 26줄 이상의 많은 코드를 작성해야 합니다. 만약 데이터의 변경이 있는 쿼리인 경우, 트랜잭션에 관한 코드도 따로 작성해야 하고, 작성해야 하는 코드의 수는 더욱 더 늘어나게 됩니다.

Spring JDBC

스프링에서 DB에 접근을 쉽게 하기 위해 제공하는 기술입니다. 앞서 언급했던 JDBC의 수많은 단점들을 해결하기 위해 만들어진 JDBC Template이 바로 이곳에 있습니다.

Spring JDBC는 기본적으로 다음과 같은 일들을 자동으로 해줍니다.

  • Connection 열기/닫기
  • Statement 준비/닫기
  • Statememt 실행
  • ResultSet Loop 처리
  • Exception 처리 및 반환
  • Transaction 처리

따라서 개발자는 오로지 JDBC Template를 위해 DataSrouce만 설정하고, sql문만 잘 작성하면 됩니다.

정리

  • JPA와 JDBC는 자바에서 제공하는 API
  • Hibernate, Driver 등은 이들의 구현체
  • Spring Data JPA는 JPA를 간편하게 사용할 수 있게 하는 스프링에서 제공하는 기능

여담

JPA 3에서의 패키지 변화

기존 JPA 2에서는 Java EE임을 알려주는 javax 패키지를 사용했습니다. 하지만 최근에 Java EE에서 Jakarta EE로 공식 명칭이 바뀌고 새로운 프로젝트를 만들면서 모든 패키지의 이름이 javax 에서 jakarta로 바뀌었고, JPA도 2에서 3으로 올라가면서 해당 패키지의 변경이 적용되었습니다.

//JPA 2
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.EntityManager;
//JPA 3
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.EntityManager;

따라서 스프링 부트 3이상을 쓰거나 JPA 3을 쓰게 되면 위와 같은 패키지를 사용해야 합니다.

참조

https://skyblue300a.tistory.com/7
https://blog.neonkid.xyz/223
https://spring.io/projects/spring-data-jpa
https://suhwan.dev/2019/02/24/jpa-vs-hibernate-vs-spring-data-jpa/

profile
정리정리

0개의 댓글