백엔드/스프링, 스프링부트, JPA, Spring Webflux

[OOP] ORM, JPA, Hibernate가 무엇인지 알아보자

Kangjieun11 2023. 5. 3. 00:15
728x90

 

✅ 개요

 

JPA를 사용하기 위해 알아야하는 키워드가 너무  많아서 당황했었던 기억이 난다. 

ORM, JPA, Hibernate, .... 

 

각 용어에 대해 알아보고, 무엇이 장점인지 좀더 명확하게 알아보면 기술을 좀더 제대로 이해하고 사용할 수 있다.

 

 

 

1️⃣ ORM

Object Relational Mapping

 

한마디로 말하면   RDBMS의 테이블과 OOP를 연결하는 기술이다. 

데이터베이스에 데이터를 생성, 수정, 읽기, 삭제하는 과정을 객체지향프로그래밍적으로 비즈니스 로직 단에서 좀 더 쉽게 다루기 위해 만들어진 기술이다.

 

(자바 진영에 국한된 기술은 아님)

 

 

🖥 Example

만약 데이터베이스에  <회원> 테이블이 있다고 가정하자.

회원 테이블에는 이름, 성별, 나이 등의 Column을 갖고 있다.


전체 유저를 검색하려고 하는데, DB로 어떻게 접근해서 작성해야할까?

당연히 SQL문을 직접 작성할 수 있다.  

 

MySQL에서는 다음 쿼리를 작성할 것이다.

SELECT * FROM members;

 

✔️ ORM을 사용하면 어떻게 될까?

<회원>테이블과 매핑된 Member 객체가 존재한다면

Member member ; 로 선언되어 있을 것이고

member.findAll()과 같이 메소드 호출로 데이터를 조회할 수 있다. 

 

 

우리가 직접 쿼리를 짜지 않고도 쿼리를 실행할 수 있어서 ORM을 사용하면 생산성이 높아진다. 

 

 

🖥 만약 DB 벤더를 변경해야하는 상황이 발생하면?

ORM은 특정 DB벤더에 의존하지 않는다.

추상화된 DB 계층을 제공함으로써 DB벤더의 특정 기능에 의존하지 않고도, 동일한 코드로 다양한 DBMS를 사용할 수 있다는 장점이 있다!

 

 

 

요약 : DB벤더에 의존하지 않은 코드를 작성, DBMS변경에 유연함, 개발자가 더 쉽게 코드를 작성할 수 있음.

 

 

🤔 단점은 없을까?

  • 쿼리가 복잡해졌을때 ORM으로 표현하는것에 한계가 있다.
  • ORM이 제공하는 다양한 기능에 의해 사용되지 않는 기능도 포함될 수 있다. 
  • (성능) 객체와 DB간 매핑을 처리하기 위한 리소스가 사용된다.

 

 

 

2️⃣ JPA

Java Persistent API

자바 ORM 기술에 대한 표준 명세 

 

자바 객체와 DB테이블 매핑을 쉽게 구현할 수 있다.

 

JPA는 ORM을 사용하기 위한 인터페이스를 모아둔 것이다. 

인터페이스이므로 구현체가 필요하다. (대표적으로 사용되는 구현체는 Hibernate)

 

 

 

🤔 JPA 와 JDBC의 비교 

두개 모두 자바를 사용해 DB와 상호작용하는 기술이다.



1. JDBC는 자바를 사용해 DB와 상호작용하는데, DB에 직접 쿼리를 실행하기 떄문에 SQL을 명시적으로 작성해줘야한다. 

2. JPA는 ORM이 기반이어서 객체 지향적인 방식으로 DB를 다룰 수 있다. 따라서 SQL 쿼리를 직접 작성하지 않아도 된다.

JPA는 객체와 DB간 매핑을 처리하기 위해 JDBC를 내부적으로 사용한다.

 

 

JPA를 사용하면 객체지향적으로 다루고, 자바 단에서 코드를 작성할 수 있기 떄문에 컴파일타임에 오류를 확인할 수 있다는 장점도 존재한다.

 

 

🔎 JPA의 장점 5가지

이전에 공부를 했었지만 다시 상기시키기 위해 간단하게 정리한다.

 

1) 1차캐시 : 영속성 컨텍스트 내부의 캐시를 사용함으로써 영속상태인 엔티티들을  DB에서 다시 조회하지 않고, 캐시에서 데이터를 가져온다. -> 불필요한 DB조회를 줄일 수 있다.

 

2) 동일성 보장 : 같은 엔티티를 조회할때 동일한 객체를 반환한다 (동일성이 보장된다)

 

3) 트랜잭션을 지원하는 쓰기 지연 : 엔티티 매니저가 트랜잭션 커밋 전까지는,  필요한 쿼리를 쓰기지연 SQL저장소에 모아둔다. 트랜잭션 커밋시에 DB에 보낸다. 

 

4) 변경 감지 (dirty cheking) :  엔티티를 조회하고 상태가 변경되면 자동으로 DB에 반영한다. (최초 상태를 복사해 저장(스냅샷)해두기 때문에 변경을 감지할수 있다) 개발자가 별도로 변경을 추적하거나 업데이트 쿼리를 작성할 필요가 없다. 

 

5) 지연 로딩 :  엔티티와 연관된 객체를 필요한 시점에 가져오는 지연로딩이 지원된다. A와 B가 일대다 관계에 있을 때 A를 조회할때 B를 가져오지 않고, B가 필요한 시점 (B를 사용하는 시점)에 가져올수 있다.

 

 

3️⃣ Hibernate

하이버네이트는 대표적으로 사용되는 JPA의 구현체 프레임워크이다. 

JPA표준을 준수하면서 많은 확장성과 유연성을 제공한다는 장점이 있다.

 

 

  1. ORM을 위한 다양한 기능 제공
  2. 다양한 DB를 지원해 , 대부분의 데이터베이스를 사용할 수 있다.
    1. JPA는 추상화된 데이터 접근 계층을 제공해 -- 특정 벤더에 종속적이지 않다.
    2. 설정 파일에서 어떤 DB를 사용하고 있는지 알려주기만 하면 된다.

 

🤔 MyBatis 와 Hibernate의 비교

 

이전에 스프링을 사용해 MyBatis를 적용했던 프로젝트와 

스프링부트 + JPA를 사용함으로써 Hibernate의 프로젝트를 통해 각각을 비교해보겠다.

 

 

MyBatis

SQL쿼리와 객체를 직접 매핑해 DB와 상호작용

-> 직접 개발자가 SQL쿼리를 작성하고 쿼리 결과를 객체에 매핑한다.

 

 

XML파일을 이용해 테이블과 직접 매핑해 쿼리문을 작성하는것을 확인할 수 있다.

 

아래는 내 예전 코드!

 

 

Hibernate

자동으로 SQL쿼리가 생성되고, 쿼리 결과를 객체에 매핑한다.

아래 이미지는 내가 스프링부트 프로젝트에서 직접 요청을 보냈을때 실행되는 쿼리문을 로그로 보여준다.

 

org.hibernate.SQL -- hibernate가 사용되며

쿼리문이 자동으로 생성되는것을 확인할 수 있다.

 

 

 


 

 

JPA를 사용함으로써 개발의 속도가 향상된다는 아주 강력한 장점이있지만

내가 의도한대로 잘 작동을 하는지 검증하는 추가 작업도 필요하다.

또 지연로딩에 의해 N+1문제가 발생할 수 있으니 성능상 검사도 지속적으로 해줘야한다.

 

 

 개발 의도와 서비스에 대해 잘 작동하는지 검증을 확실하게 하자!

 

 

https://victorydntmd.tistory.com/195