JPA? JDBC?

JDBC, 스프링 JDBC, JPA, 하이버네이트, 스프링 데이터 JPA…

스프링 프로젝트에서 자바로 데이터를 처리하거나 DB에 접근할 때 꼭 필요한 단어들이다. JPA 리포지토리의 파생 쿼리와 같은 실용적인 기능만 작성하느라 바빴고, 프로젝트 구현에만 집중했으며, 기본 기술의 정확한 원리와 역사는 건너뛰었습니다. 그러는 동안 프로젝트를 진행하면서 ‘이건 아마 이런 거겠지’ 하고 생각해서 시간을 내서 정리를 해봐야겠습니다!

1. JPA: ORM 가이드

자바 퍼시스턴스 API 사용 ORM(Object Relational Mapping)은 JAVA 언어 자체에서 제공 기술 표준 세부오전.

ORM 프레임워크를 이용하면 MySQL, MariaDB와 같은 DB 관계형 테이블과 Java 객체를 매핑하여 SQL 문을 직접 작성하지 않고 객체 관련 메소드를 호출하기만 하면 DB 데이터에 접근할 수 있습니다. ORM 기술은 자바 애플리케이션 개발 과정에서 DB에 연결하고 SQL을 작성하는 데 많은 시간을 소비하는 것이 자바의 객체지향 패러다임에 맞지 않기 때문에 발전한 것으로 보인다.

어쨌든 JPA는 간단히 말해서 Java로 ORM을 작성하는 경우 이 형식을 고수하십시오. Java로 작성된 사양입니다. 가이드에 가깝기 때문에 실제 구현은 없습니다. 상호 작용JPA에는 실제 기능이 있는 메서드가 없으므로 JPA만으로는 아무 것도 할 수 없습니다.


위 이미지에 보이는 Annotation, Enum, Interface, Exception은 JPA를 정의하는 내용들이다. 자카르타, 끈기 이들은 패키지 내부의 클래스입니다. Spring을 이용한 DB 프로젝트 진행 시 여러 번 사용된 Annotation이 있음을 확인할 수 있다.

오 예. Java에서 ORM 기술을 사용하는 경우 이를 구현하는 방법에 대한 지침을 제공한 것으로 알고 있습니다. 근데 지금 뭐해 구현이 없는 경우. 그러면 실제 구현 방법을 사용하여 데이터 CRUD를 진행할 수 있습니다. 개발자가 JPA를 직접 구현해야 하지 않습니까?

2. Hibernate: JPA 구현 중 가장 인기 있는 것!

물론 아닙니다(실제로 그럴 수도 있습니다! 무료 자동차가 제공되지만 직접 만들 필요는 없습니다). 스마트 개발자가 JPA를 구현한 프레임워크가 이미 여러 개 있기 때문입니다. 그 전에 자바 애플리케이션이 DB에 접근할 수 있게 해주는 기초 기술인 JDBC에 대해 알아보자.

# JDBC : 자바에서 DB접속을 위한 API 제공

JDBC는 Java Database Connectivity의 약자로 Java에서 다양한 DB에 접근하기 위한 API를 제공합니다. JDBC API를 사용하는 전체적인 과정은 다음과 같습니다.

  • 사용 중인 DB에 대한 드라이버 클래스 로드
  • 주소에 대한 DB 연결
  • 연결 개체에 쿼리 삽입 + 실행
  • 결과 데이터 처리(데이터 <-> 물체)
  • DB 연결 끊기

JDBC를 직접 사용했던 예전 코드를 보면 실제로 위의 과정이 실행된 것이다. 또한 관련된 모든 예외 처리를 수행해야 했습니다. ID로 사용자를 찾는 데 30줄 이상의 코드가 필요했습니다. 하나) DB접속 시작부터 종료까지의 과정이 길고 복잡하며, 2) 일련의 프로세스에서 발생하는 모든 Checked 예외를 개발자가 직접 처리해야 한다는 사실, 삼) DB 독립이라는 사실. 이러한 이유로 순수한 JDBC는 현재 사용되지 않습니다. (저는 자동차를 직접 만드는 변태라 JPA를 직접 구현한다고 하면 굳이 써먹어야 할지도 모르겠습니다.)

이와 별도로 Spring 환경에서 JDBC를 쉽게 사용할 수 있도록 해주는 Spring JDBC 모듈(JdbcTemplate 사용)이 있지만 로우 매퍼와 SQL 문을 직접 작성해야 하므로 많이 사용되지 않는 것 같다.

JDBC는 순수하게 사용하기에는 사용 과정이 매우 복잡하지만 Java 애플리케이션에서 DB에 연결하기 위해 반드시 사용해야 하는 API입니다. 사실 그것 때문에 Java에서 DB로 작업하는 지속성 프레임워크 JDBC 기반 프레임워크로 사용(지속성, 지속성 프레임워크가 무엇인지는 다른 글에서 설명하겠습니다.)

JPA를 구현하는 프레임워크로 돌아갑니다. Java에서 ORM 기술을 사용하기 위해 JPA를 구현하는 다양한 구현 프레임워크가 있습니다. 대표적으로 Hibernate, EclipseLink 및 DataNucleus가 있으며 Hibernate가 가장 일반적으로 사용됩니다. 역사가 오래된 만큼 다양한 기술을 보편적으로 제공하기 때문이라고 하는데, 다른 건 안 써봐서 잘 모르겠습니다.

그럼에도 불구하고 “Java에서 ORM을 사용하려면 기술 사양인 JPA를 따르는 구현체를 사용해야 합니다. 가장 대표적인 구현체가 Hibernate입니다.” 내용을 이해하시면 될 것 같습니다.

JPA 인터페이스에 구현된 컨텐츠를 이용하여 자바 어플리케이션을 구현하는 과정을 간단하게 표현한 이미지입니다.


https://www.inflearn.com/course/ORM-JPA-Basic

이 숫자는 JPA 구현이 내부적으로 JDBC API를 사용함을 확인할 수 있습니다.


JPA 구현(일반적으로 Hibernate)을 통해 DB에 액세스하는 것과 SQL 문을 직접 작성하는 것의 장단점은 무엇입니까?

장점

  • 생산력 : SQL 작성이 아닌 간단한 메소드 호출로 DB에 존재하는 데이터의 CRUD가 가능합니다. DB 연결 및 예외 처리를 위한 코드를 반복적으로 작성할 필요가 없습니다.
  • 유지 참고: SQL을 직접 작성하는 경우 테이블 구조가 변경되면 관련된 모든 SQL 문을 수정해야 하지만 JPA를 사용하면 객체 구조를 변경하는 것만으로 관련 쿼리를 수정할 수 있습니다.
  • OOP 준수 : Java 프로그래머가 SQL 작성자가 되는 대신 개체 지향 비즈니스 논리 개발에 집중할 수 있습니다.
  • DB 독립 : SQL 문은 DBMS 회사마다 조금씩 다른 문제를 해결합니다. DB 드라이버를 hibernate로 속성만 설정하면 DBMS에 맞는 쿼리가 생성됩니다.

불리

  • 성능 참고: 메서드를 쿼리문으로 변환하는 과정이 필요하기 때문에 처음부터 실행 가능한 SQL문을 제공하는 것보다 성능이 느려집니다. (처음에는 별로였지만 최근 많이 좋아진 것 같습니다.)
  • 세부 사항 : 복잡한 조건 집합을 추가하여 쿼리를 작성하는 데 제한이 있습니다. 이것은 JPA에서 직접 SQL과 유사한 쿼리를 작성할 수 있게 해주는 JPQL과 같은 기능을 사용하거나 QueryDSL을 사용하여 극복할 수 있습니다.
  • 배우다? 참고: DB접근을 추상화하는 ORM 프레임워크의 특성상 복잡한 연산은 내부에 숨겨져 있으며 제대로 이해하지 못하면 잘못된 연산이 발생할 수 있습니다.

JPA의 역할은 우리가 Java에서 객체 지향 개발에 집중할 수 있도록 하는 데 충분합니다. 최대 절전 모드, 정말 좋은 사람입니다.

그러나 저를 포함한 최근의 데이터베이스는 Hibernate로 구현된 JPA의 EntityManager를 사용한 적이 없습니다. 대신 JpaRepository를 구현하고 파생 쿼리를 사용했을 것입니다. 그래서 무엇입니까? JPA 이름이 포함되어 있어서 JPA를 사용하고 있는데 최대 절전 기능을 사용했는지 궁금하실 수 있습니다.

3. 스프링 데이터 JPA: JPA가 더 쉬워졌습니다!

리포지토리를 사용한다는 것은 Hibernate에서 제공하는 JPA 인터페이스 기능을 직접 사용하는 대신 한 단계 더 나아가는 것을 의미합니다! 추상화된 Spring Data JPA를 사용했다는 것을 이해할 수 있습니다.

Raw JPA를 사용하려면 지속성 컨텍스트에서 엔터티를 관리하기 위해 EntityManager로 트랜잭션을 열어야 합니다. 커밋을 통해 새로운 엔터티를 영구 상태로 만들 수 있고, 컨텍스트의 엔터티를 분리 및 수정한 다음 커밋을 통해 데이터를 수정하거나 쿼리를 직접 실행하거나 데이터를 삭제할 수 있습니다.

Hibernate의 EntityManager를 사용하는 예코드 흐름을 따라가면 어떻게 작동하는지 대략적으로 알 수 있습니다.

여기에서 Spring Framework는 DB 관리를 위한 고급 인터페이스, 즉 Spring Data JPA의 JpaRepository를 제공합니다. EntityManagerFactory를 통해 EntityManager를 호출하는 반복적인 코드를 작성하는 대신 JpaRepository를 사용하면 트랜잭션을 열고, 객체를 분리하고, 커밋하고, 트랜잭션을 닫고… 노출합니다. 거기에 Derived Query라는 Spring Data JPA의 강력한 기능이 있습니다. 별도로 구성하는 방법이 있습니다.

실제로 JpaRepository 구현을 보면 내부적으로 EntityManager를 사용하고 있음을 알 수 있다. 마지막으로 JPA 구현을 보다 쉽게 ​​사용할 수 있는 고급 추상화 인터페이스입니다. JpaRepository 사용 시 일반적으로 사용 가능한 findById() 내에서 JPA의 EntityManager.find() 메서드를 사용하도록 체크합니다.

package org.springframework.data.jpa.repository.support;

import ...

public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {

    private final EntityManager em;

    public Optional<T> findById(ID id) {

        Assert.notNull(id, ID_MUST_NOT_BE_NULL);

        Class<T> domainType = getDomainClass();

        if (metadata == null) {
            return Optional.ofNullable(em.find(domainType, id));
        }

        LockModeType type = metadata.getLockModeType();

        Map<String, Object> hints = getQueryHints().withFetchGraphs(em).asMap();

        return Optional.ofNullable(type == null ? em.find(domainType, id, hints) : em.find(domainType, id, type, hints));
    }

    // Other methods...
}

“Spring Data JPA는 Hibernate와 같은 JPA 구현의 사용을 단순화하는 Spring Data 라이브러리입니다.”

내가 고칠 수 있어.

또한 Hibernate는 Spring Data JPA 환경에서 JPA 구현으로 채택됩니다.

아래 그림은 JPA와 이를 구현하는 Hibernate, 기반이 되는 JDBC, JPA를 편리하게 사용할 수 있도록 Spring Data JPA의 관계를 한눈에 정리한 것이다.


참고로 Spring Data JPA는 Spring Data 프로젝트의 일부이며 JPA 구현이 아닌 MongoDB를 사용하는 경우 JpaRepository 대신 MongoRepository를 사용할 수 있습니다.

참조)

https://suhwan.dev/2019/02/24/jpa-vs-hibernate-vs-spring-data-jpa/

https://velog.io/@adam2/JPA%EB%8A%94-%EB%8F%84%EB%8D%B0%EC%B2%B4-%EB%AD%98%EA%B9%8C -orm-%EC%98%81%EC%86%8D%EC%84%B1-hibernate-spring-data-jpa