소통하는 개발자 Sean
article thumbnail

🧭 Part1. 질문

여러분들은 ORM, JPA, Hibernate, Spring Data JPA, EntityManager, Repository의 차이와 관계를 설명할 수 있나요?

 

저도 JPA를 사용하고 있지만 ORM, JPA, Hibernate, Spring Data JPA, EntityManager, Repository 차이 대해 궁금증이 생겼습니다. 어떻게 설명해야 할지, 설명하면서 내가 몰랐던 부분(메타인지)이 어디였는지 알아보도록 하겠습니다!

글이 조금 길다고 느껴지시면 Part3 요약으로만 보셔도 좋습니다!

 

🧭 Part2. 알아보기

👉 2-1. 그림부터 보면서 친숙해지기

 

👉 2-2. ORM

👻 2-2-1. ORM ?

 

ORM(Object-Relational Mapping)은 데이터베이스의 테이블을 객체로 매핑하여, 데이터를 객체지향적으로 조작할 수 있게 해주는 프로그래밍 기술입니다.

ORM은 SQL문법 대신 어플리케이션의 개발언어(ex. Java)를 그대로 사용하여, 메소드를 만들고 SQL데이터를 생성하고 조회할 수 있기 때문에 가독성이 높아지고 개발언어를 일관되게 활용할 수 있어 편리합니다.

데이터베이스 작업을 추상화하여 개발 과정을 단순화하고 개발 시간을 단축시키는데 도움을 줍니다. (여기서 말하는 추상화는 데이터베이스의 세부 기능들을 직접 다루지 않고 편리한 기능 하나로 나머지 부분들이 착착착 진행되는걸 말합니다)

 

👻 2-2-2. ORM의 종류 ?

사용하는 프로그래밍 언어에 따라 다양한 ORM 프레임워크를 제공합니다. Java 개발자에게 친숙한 Hibernate도 있네요.

  1. Hibernate (자바): 가장 널리 사용되는 ORM 프레임워크 중 하나로, 데이터베이스와의 상호작용을 추상화하여 개발자가 JDBC를 직접 다루지 않아도 되게 합니다.
  2. Django ORM (파이썬): Django 웹 프레임워크에 포함된 ORM으로, 파이썬 개발자가 데이터베이스 작업을 쉽게 할 수 있도록 지원합니다.
  3. Sequelize (Node.js): Node.js 애플리케이션을 위한 Promise 기반 ORM으로, PostgreSQL, MySQL, MariaDB, SQLite, 그리고 Microsoft SQL Server를 지원합니다.
  4. SQLAlchemy (파이썬): 파이썬에서 사용할 수 있는 또 다른 강력한 ORM 라이브러리로, 복잡한 SQL 쿼리와 데이터베이스 스키마를 쉽게 관리할 수 있습니다.

 

👻 2-2-3. ORM의 장단점과 적절한 활용 방향

SQL언어가 아닌 사용하는 프로그래밍 언어(Java, Python..)으로 DB를 다룰 수 있어 언어의 일관성이 있다는 점이 참 좋은 것 같습니다.

장점 뿐만 아니라 단점은 어떤 것들이 있는지 알아보겠습니다.

 

단점

  1. 성능 저하: ORM을 사용하면 SQL 쿼리가 추상화되기 때문에, 때때로 직접 작성한 SQL보다 성능이 떨어질 수 있습니다.
  2. 복잡한 쿼리의 어려움: ORM은 일반적인 CRUD(Create, Read, Update, Delete) 작업에 최적화되어 있어, 복잡한 쿼리나 최적화가 필요한 상황에서는 한계를 보일 수 있습니다.
  3. 학습 곡선: ORM을 효과적으로 사용하기 위해서는 해당 ORM의 작동 방식과 객체 지향 프로그래밍에 대한 충분한 이해가 필요합니다.

적절한 활용 방향

  • 프로토타이핑과 중소규모 프로젝트: 빠른 개발이 요구되거나, 데이터베이스 작업이 많지 않은 프로젝트에 적합합니다.
  • 복잡도가 낮은 CRUD 작업이 많은 애플리케이션: 간단하고 반복적인 데이터베이스 작업이 주를 이루는 경우, ORM을 통해 개발 속도와 유지 보수성을 향상시킬 수 있습니다.
  • 데이터베이스 독립적인 애플리케이션 개발: 다양한 데이터베이스 환경을 지원해야 하는 경우, ORM을 사용하여 데이터베이스 변경에 따른 코드 수정 작업을 최소화할 수 있습니다.

복잡한 쿼리가 많거나, 최적화가 중요한 대규모 애플리케이션에서는 ORM의 사용을 신중히 고려하고, 필요에 따라 ORM과 직접 쿼리를 적절히 혼용하는 전략을 선택할 수 있습니다.

 

👉 2-3. JPA

👻 2-3-1. JPA ?

 

JPA는 Java Persistence API의 약자로, 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스입니다.

여기서 중요하게 여겨야 할 부분은, JPA는 말 그대로 인터페이스라는 점입니다. JPA를 구현한 구현체는 따로 있습니다. ORM이라는 아이디어를 자바로 표현해본게 JPA 인거죠.

 

JPA를 정의한 javax.persistence 패키지의 대부분은 interface, enum, Exception, 그리고 각종 Annotation으로 이루어져 있습니다. 예를 들어, JPA의 핵심이 되는 EntityManager는 아래와 같이 javax.persistence.EntityManager 라는 파일에 interface로 정의되어 있습니다.

package javax.persistence;

import ...

public interface EntityManager {

    public void persist(Object entity);

    public <T> T merge(T entity);

    public void remove(Object entity);

    public <T> T find(Class<T> entityClass, Object primaryKey);

    // More interface methods...
}

JPA를 사용하기 위해서는 JPA를 구현한 Hibernate, EclipseLink, OpenJPA와 같은 JPA의 구현체를 사용해야합니다.

 

👉 2-4. Hibernate, EclipseLink, OpenJPA

👻 2-4-1. Hibernate, EclipseLink, OpenJPA ?

 

위에서 설명했듯이 여러분들이 잘 아시는 Hibernate는 JPA라는 명세의 구현체입니다. 유명한 Hibernate 외에도 EclipseLink, OpenJPA 등 다양한 구현체들이 존재합니다.

 

좀 더 깊게 들어가보자면, Hibernate와 같은 JPA 구현체들은 앞서 코드로 설명한 javax.persistence.EntityManager와 같은 인터페이스를 직접 구현한 라이브러리입니다. JPA와 Hibernate는 마치 자바의 interface와 해당 interface를 구현한 class와 같은 관계인 셈입니다.

 

위 사진은 JPA와 Hibernate의 상속 및 구현 관계를 나타낸 것입니다. JPA의 핵심인 EntityManagerFactory, EntityManager, EntityTransaction을 Hibernate에서는 각각 SessionFactory, Session, Transaction으로 상속받고 각각 Impl로 구현하고 있음을 확인할 수 있습니다.

 

👻 2-4-2. Must Hibernate ?

그럼 우리는 꼭 Hibernate만 사용해야할까요? 그렇지는 않습니다. Hibernate의 작동 방식이 마음에 들지 않는다면 언제든지 EclipseLink, OpenJPA와 같은 다른 JPA 구현체를 사용해도 됩니다.

  • Hibernate는 가장 널리 사용되는 JPA 구현체 중 하나로, 강력한 ORM(Object-Relational Mapping) 기능을 제공합니다. Hibernate는 초기에 독자적인 ORM 프레임워크로 시작했지만, 현재는 JPA 명세의 구현체로도 널리 사용됩니다.
  • EclipseLink는 Eclipse Foundation이 관리하는 JPA 구현체로, Java EE와 Jakarta EE의 참조 구현으로 사용됩니다. 초기에 Oracle이 TopLink라는 이름으로 개발했으나, 이후 오픈소스 커뮤니티에 기부되어 EclipseLink가 되었습니다.
  • OpenJPA는 Apache Software Foundation에서 관리하는 또 다른 JPA 구현체입니다. OpenJPA는 엔터프라이즈 급 애플리케이션을 지원하기 위한 다양한 기능을 제공합니다.

 

그럼에도 Hibernate를 사용하는 이유는 몇가지가 있습니다.

  1. 오랜 기간 동안 발전해왔기 때문에 대규모 프로젝트와 복잡한 데이터 모델에서도 검증된 성능과 안정성을 보여줍니다.
  2. 활발한 커뮤니티와 풍부한 문서를 보유하고 있습니다.
  3. Spring Boot가 Spring Data JPA를 사용할 때 Hibernate를 기본 JPA 구현체로 자동 설정합니다.

 

👉 2-5. Spring Data JPA

👻 2-5-1. Spring Data JPA ?

 

JPA 공부를 하다보면 EntityManager를 통해 entity관련 CRUD를 한다고 나와있습니다. 하지만 저의 경우 실제 애플리케이션 코드 구현시 EntityManager를 사용하지 않고 Repository 인터페이스를 사용했었는데요. 알고보면 JPA를 한 단계 추상화시켜 Repository라는 인터페이스를 제공한 것입니다.

 

사용자가 Repository 인터페이스에 정해진 규칙대로 메소드를 입력하면, Spring이 알아서 해당 메소드 이름에 적합한 쿼리를 날리는 구현체를 만들어서 Bean으로 등록해줍니다.

 

Spring Data JPA가 JPA를 추상화했다는 말은, Spring Data JPA의 Repository의 구현에서 JPA를 사용하고 있다는 것입니다. 예를 들어, Repository 인터페이스의 기본 구현체인 SimpleJpaRepository의 코드를 보면 아래와 같이 내부적으로 EntityManager을 사용하고 있는 것을 볼 수 있습니다.

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...
}

 

 

👻 2-5-2. Spring Data JPA는 기본적으로 Hibernate 선택 ?

Spring Data JPA 자체는 어떤 특정 JPA 구현체를 기본값으로 "선택"하지 않습니다. 그러나 Spring Boot를 사용할 때 spring-boot-starter-data-jpa 스타터를 포함하면, Spring Boot의 자동 구성 기능이 Hibernate를 JPA 구현체로 기본적으로 설정합니다. (알게 모르게 다 해주고 있는 무서운 Boot..)

 

👻 2-5-3. 만약 Spring Data JPA를 사용하지 않고 JPA만 사용한다면?

Spring Data JPA를 사용하지 않고 순수 JPA만을 사용하는 경우, JPA 구현체를 직접 선택하고 설정해야 합니다. 설정을 한다고 하더라도, 추상화가 잘 된 Repository를 사용하지 못하고 EntityManager로 직접 이것저것 설정해 주어야 하기 때문에 불편할 듯합니다…!

 

데이터 접근 코드를 보다 세밀하게 제어할 수 있게 해주지만, 반면에 설정과 코드의 양이 늘어나 개발 생산성이 다소 떨어질 수 있습니다. 따라서, 프로젝트의 요구사항과 개발자의 선호에 따라 순수 JPA 사용 여부를 결정해야 합니다.

 

👉 2-6. 이걸 다 합치면?

아래 사진은 위의 내용을 요약하여 JPA, Hibernate, 그리고 Spring Data JPA의 전반적인 개념을 그림으로 표현한 것입니다.

.

위의 설명을 쭉 보면서 내려오시니 이제 이해가 되시나요??

 

🧭 Part3. 요약

  • ORM : DB를 다룰 때 SQL은 따로 배워야하잖아, 프로그래밍언어(ex. Java)로 DB를 다루고 싶어!
  • JPA : Java를 사용한 ORM이 있을까??
  • Hibernate : JPA는 인터페이스라 이것을 구현한 구현체가 필요해! 그 중 잘만든게 뭐가 있어?
  • Spring Data JPA : Hibernate 좋긴한데 EntityManager를 내가 직접 다뤄야해서 좀 귀찮아.. 좀 더 편하게 사용못할까?


REF

profile

소통하는 개발자 Sean

@Sean-creative

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!