동글이기가 레포

ORM

ORM에 들어가기 앞서, Persistence 속성에 대해 먼저 알아보자.

 

영속성(Persistence) 특성은 프로그램이 종료되더라도 사라지지않는 비휘발성 데이터라는 특성을 말한다.

만약, 영속성 특성이 없는 데이터(휘발성)는 메모리상에서만 존재하기 때문에 프로그램이 종료되면 모두 날라간다.

 

1) Object Persistence(영구적인 객체)

메모리 상의 데이터를 file system, RDB(관계형 데이터베이스) or 객체 DB를 활용하여 영구적으로 저장(영속성)

  - java에서는 JDBC사용
  - Spring JDBC

  - Hibernate, Mybatis 등의 프레임워크 이용

 

2) Persistence Layer

프로그램 상의 아키텍처에서 데이터에 영속성을 부여하는 계층이다.

  - JDBC를 이용하기도 하지만, 주로 Hibernate나 Mybatis등의 프레임워크를 많이 사용한다.

 

3) Persistence Framework

위에서 언급했지만, JDBC를 활용할때의 복잡함없이 간단한게 DB와 연동하는 시스템을 개발할 수 있다.(안정적이기도 함)

이는 SQL Mapper와 ORM으로 나눠질 수 있다.

  - JPA(ORM), Hibernate(ORM), Mybatis(SQL Mapper) 등

 

 

ORM은 Object Relational Mapping의 약자로서 말 그대로 객체와 관계를 매핑한다는 뜻이다.

풀어서 말하면 객체와 관계형 데이터베이스(RDB)의 데이터를 자동으로 매핑해주는 것이다.

  - 객체 지향 프로그래밍에서는 class를 이용하고, 관계형 데이터베이스에서는 Table을 사용

 

객체 모델과 관계형 모델간에는 불일치가 존재하는데, 이를 해결하기 위해 ORM으로 SQL을 자동 생성한다.

(DB 데이터 - 매핑 - Object)

ORM은 Persistant API라고도 한다(JPA나 Hibernate 등)

 

 

이러한 ORM을 왜 사용할까?

 

ORM을 사용하면 객체 지향적인 코드로 인해 직관적이고 비즈니스 로직에 더 집중할 수 있다.

  - SQL Query를 직접적으로 사용하는 것이 아닌 메소드(코드)로 데이터를 조작하기 때문에 개발자 입장에서 프로그래밍에만 집중할 수 있게 도와준다.

// ex) MySQL
SELECT * FROM user;

// ORM
user.findAll()

    > 이는 선언문, 할당, 종료와 같은 부수적인 코드를 확연하게 줄일 수 있기 때문이기도 하다.

    > 각종 객체에 대해서 따로 개발하기 때문에 가독성을 올려준다.

  - 재사용과 유지보수에 효과적이다.

  - DBMS에 대한 종속성이 줄어든다.

    > 객체 간의 관계를 바탕으로 SQL을 자동으로 생성하기 때문에 RDBMS의 데이터 구조와 java의 객체지향 모델 사이의 간격을 좁힐 수 있다.

 

그러나, 물론 단점도 존재한다.

 

ORM이 아무리 간편하다고 하더라도 이것만으로는 정상적인 서비스를 구현하기가 힘들다.

프로젝트의 난이도에 따라 설계도 매우 신중해져야 하며, 간편하다고 안일하게 설계했다간 성능에 심한 타격을 줄 수 있다.

그리고 많이 쓰는 쿼리에 대해서는 별도 튜닝이 필요하다.

 

정리하자면

ORM은 쿼리를 직접 장성하지 않고 메소드 호출만으로 처리가 가능하기 때문에 생상성이 매우 높아진다.

그러나, 쿼리가 복잡해질수록 ORM으로 표현하는데 한계가 있고(아래 QueryDSL 포스팅 참고) 성능이 raw query보다는 느리다(당연히 거치는 것이 있기 때문에)

그래서 JPQL이나 QueryDSL을 사용하거나 한 프로젝트 내에서 Mybatis와 JPA를 같이 사용하기도 한다.

 

 

JPA

JPA(Java Persistent API)의 약자로 ORM 기술에 대한 표준 명세를 정의한 것이다.

말 그대로 JPA는 표준 명세일 뿐이라서 JPA만 가지고서는 실제로 구현을 할 수 없다.

 

JPA 표준 명세를 실제로 구현한 구현체로는 Hibernate, EclipseLink, DataNucleus, OpenJPA 등이 있다.

이러한 구현체들은 ORM Framework, JPA 구현체, JPA Provider 등으로 불린다.

(만약, Spring boot에서 Spring Data JPA 의존성을 주입하면, 디폴트로 Hibernate가 연동된다)

 

JPA개념이 있기 전에는 위 사진을 참고하면 JDBC를 사용하여 직접 DB와 연결하고 쿼리를 날리는 방식을 사용하곤 했다.

그러나, 이러한 방식은 유지보수나 재사용성에 있어서 좋지 못한 방법이다.

그래서 DB 연결이나 쿼리의 재사용성을 개선하고자 만들어진 프레임워크가 SQL-Mapper이다.

 

SQL Mapper도 잘 사용되었으나, 쿼리가 xml로 관리되어지기 때문에 유지보수 이슈는 끊임없이 발생하였다.

빌드 과정에서 오류가 발생하면 쿼리와 관련있는 DAO를 찾아야 했기 때문이다.

 

이러한 모든 이슈를 개선하고자 만든 것이 Hibernate와 같은 프레임워크이다.

그동안의 불편함을 해소하고, 유지보수에서는 type safe라는 개념을 통해 간단한 빌드와 테스트코드만으로도 유지보수가 용이해져서 생산성을 높이게 된 것이다.

(물론, SQL Mapper도 복잡한 쿼리 처리등의 강점은 존재한다)

 

JPA vs SQL Mapper

위에서는 계속 말로만 비교했는데, 실제로 사용에 대한 차이점을 비교해보자

 

1. 삽입(INSERT)

SQL Mapper
INSERT INTO USER(name, phone) VALUES('홍길동', '01012345678')

JPA
User user = new User('홍길동', '01012345678');
em.persist(user)

 

2. 변경(UPDATE)

SQL Mapper
UPDATE USER SET name='홍길동' WHERE id=3

JPA
//user 객체를 찾았다는 가정하에
User user = em.find(User.class, 3);
user.setName('홍길동')

 

3. 삭제(DELETE)

SQL Mapper
DELETE FROM USER WHERE user_id=3;

JPA
User user = em.find(User.class, 3);
em.remove(user);

위 예시들은 간단해서 차이를 못 느낄수도 있지만, 필요한 형식의 데이터를 파싱해서 SQL에 넘겨주는 코드를 작성해야하는 개발자의 입장에서는 다를 수 있다.

그리고 모든 과정에서 JPA는 계속 SQL을 생성하지 않아도 된다.

  - 도메인 중심으로 Data를 가져오기 때문에 재사용성도 증가

 

 

 

참고

https://kooku.netlify.app/spring-boot%20&%20Java/JPA%20ORM%20JDBC%20%EB%9E%80/

 

 

'스터디 > Spring 스터디' 카테고리의 다른 글

[JDBC] JDBC란?  (0) 2022.04.17
[DB]intellij 프로젝트 h2 DB 연동  (0) 2022.04.16
인증 관련 JWT 작성  (0) 2022.03.29
여러가지 에러 대응  (0) 2022.03.27
JWT의 한계점과 보완점  (0) 2022.03.23

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading