ORM이란?

niireymik·2024년 2월 3일


ORM이 무엇인지 검색하면, Persistence Framework는 두 가지 : SQL Mapper와 ORM으로 나뉜다는 것을 알 수 있다. 그럼 이 Persistence Framwork는 무엇인가? 하는 질문으로 접어들면 그때부터 영속성, 영구적인 객체, JDBC, Spring JDBC까지 깊은 심연으로 접어든다 ... 🤯

그러나 지금은 ORM이 주제이니! ORM을 이해하는 데 필요한 개념 정도만 함께 알아본 뒤, ORM을 톺아보도록 하자 ( •̀ ω •́ )✧




📍 Persistence Layer

Persistence Layer(영속성)
: 데이터를 생성한 프로그램이 종료되더라도 생성된 데이터는 사라지지 않는 특성을 말한다.

영속성을 갖지 않는 데이터는 프로그램을 종료하면 모두 잃어버리게 된다. 따라서 프로그램 종료 여부와 관계 없이 필요한 데이터에 대해, 파일 시스템이나 데이터베이스를 활용하여 데이터를 영구적으로 저장함으로써 영속성을 부여한다.

Layerd Architecture : 계층화 아키텍처는 위처럼 Presentation Layer, Business Logic Layer, Data Access Layer 세 레이어로 뉜다. 프레젠테이션 층은 사용자 인터페이스와 컨트롤러를 제공하고, 비스니스 로직 층은 비즈니스 로직을 제공하며, 데이터 액세스 층은 데이터 액세스를 추상화한다.

Persistence Layer : 영속 계층은 이름처럼 데이터에 영속성을 부여해주는 계층이며, 계층화 아키텍처의 Data Access Layer와 같은 의미이다.


📍 JDBC (Java Database Connectivity)

JDBC는 자바에서 데이터베이스에 접속하고, 데이터를 조회하거나 저장하는 등의 기능을 사용할 수 있도록 만든 자바 표준 인터페이스이다.

JDBC가 없던 시절에도 당연히 자바에서 DB를 사용할 수 있었다.
그러나! DB 회사가 만든 각자의 라이브러리를 직접 가져다 써야 하는 불편함이 있었다. 즉, MySQL을 사용하려면 MySQL 전용 API를 사용해야 했다. 각 DB 회사별 API는 구조는 물론 사용법이 천차만별이었기에 DB를 변경하려면 코드 전체를 뜯어 고쳐야 하는 치명적인 단점이 있었다.

이러한 벤더 종속성을 해결하기(줄이기) 위해 표준이 필요해졌고, Sun Microsystems(현재의 Oracle)이 자바 진영에서 공식 표준 인터페이스로 내놓은 것이 바로 JDBC이다. 개발자는 JDBC API를 사용하여 항상 같은 방식으로 DB에 접근하고, DB 제공 업체는 JDBC 인터페이스에 맞는 드라이버를 제공하기만 하면 되게 된 것이다 ! :)

드라이버?
: Oracle, MySQL 등 각 데이터베이스 벤더들이 JDBC 표준 인터페이스를 자신들의 데이터베이스 명세에 맞도록 구현한 구현체들을 제공하는데, 이를 JDBC 드라이버라고 한다. 예를 들어, MySQL에서 JDBC 표준 인터페이스를 구현한 구현체는 MySQL JDBC 드라이버라고 부른다.

하지만 JDBC를 직접 사용하는 데에는 여러 불편함과 한계가 있었다. 반복되는 보일러 플레이트 코드, 복잡한 예외처리, 객체 수동 매핑, 트랜잭션 관리의 어려움 등이 대표적인 문제점이었다.


📍 Spring JDBC

Spring 프레임워크는 앞서 짚은 JDBC의 단점을 보완하기 위한 Spring JDBC라는 모듈을 제공한다. JDBC를 래핑한 API를 제공함으로써 소스 코드를 단순화했으며, JDBC를 직접 사용할 때 발생하는 장황한 코드를 은닉했다. 보일러 플레이트를 제거하고, 템플릿(JdbcTemplate) 기반으로 접근하도록 하고, 객체 매핑(RowMapper)을 지원하며, 일관된 예외 처리가 가능하도록 하고, 트랜잭션도 보다 쉽게 관리할 수 있도록 한 것이다 ! :>

그러나 여기서도! 또다시 문제점이 떠오른다. (현대에 개발하는 나는 참 운이 좋다 .. ^____^)
JDBC를 사용해 보면 코드가 굉장히 복잡하다는 것을 느낄 수 있다. 실제로 사용되는 SQL문은 몇줄 안 되지만 Connection 연결부터 수많은 코드 작성이 요구된다. ~JDBC는 살면서 다시는 보고 싶지 않다는 생각을 하게 된다...~


📍 Persistence Framework

위와 같은 부분을 보완하여 아주 간단한 작업만으로 데이터베이스와 연동할 수 있도록 해주는 프레임워크가 Persistence Framework이다! :>

Persistence Framework는 다음의 2가지 종류로 나뉜다.

  • SQL Mapper (ex. MyBatis)

    • SQL 문장으로 직접 데이터베이스 데이터를 다룸
    • SQL 직접 작성, 결과 매핑도 명시적으로 설정하므로 자유도가 높음
    • SQL 중심 : 쿼리가 로직의 중심
    • SQL을 완벽히 제어할 수 있고 복잡한 JOIN 등에 강하나, 객체지향적 코드 구조로 발전시키기 어려움
  • ORM (ex. JPA, Hibernate)

    • 객체를 통해 간접적으로 데이터베이스를 다룸
    • SQL 없이 자바 객체(Entity)로 DB 조작, 기본 CRUD는 SQL 없이 자동 처리되므로 편리함
    • 객체 중심 : 엔티티가 로직의 중심
    • 코드만으로 DB 연동이 가능하고 객체 지향적 설계가 가능하나, 복잡한 쿼리는 오히려 작성이 불편하거나 성능 문제 발생 가능성이 있음

🧐 JDBC Template도 SQL Mapper에 포함되지 않나요?
JdbcTemplate이 SQL을 직접 쓰는 방식이라는 점에서 JdbcTemplate과 MyBatis를 비슷한 분류로 보고, 둘 다 SQL Mapper라고 표현하는 경우가 있다. 그러나 정확한 기술 분류로는 옳지 않다.
JdbcTemplate은 Spring JDBC의 핵심 클래스일 뿐이며, 기본적으로 '프레임워크'도 아님을 알아두자! :)

→ 이중 ORM이 오늘 공부하려는 주제이다! 이제 본격적으로 ORM에 관해 톺아보도록 하자 :>




📌 ORM이란?

: Object-Relational Mapping의 약자로, 직역하면 객체-관계 매핑이다. 이는 말 그대로 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결) 해주는 것을 말한다. 대표적인 ORM으로는 JPA, Hibernate가 있다.

ORM의 역할은 다음과 같은 말들로 표현할 수 있다.

  • 프로그래밍 언어의 객체와 관계형 DB 사이의 중계자(통역자)
  • MVC 패턴에서 모델(Model)을 기술하는 도구
  • 객체와 모델 사이의 관계를 기술하는 도구

ORM의 역할: 왜 사용할까?

객체 지향 프로그래밍(OOP)은 클래스를 사용하고, 관계형 DB는 테이블을 사용하기에 당연히 두 모델은 일치하지 않는다. 그럼에도 불구하고 객체와 관계형 DB는 연관성이 깊어 서로 호환될 수 있어야 한다. 따라서 객체 간의 관계를 바탕으로 SQL을 자동으로 생성하여 불일치를 해결하는데, 그 역할을 하는 주체가 바로 ORM인 것이다. ORM은 데이터베이스와 객체를 연결(Mapping) 해주는 역할을 하고, 객체를 통해 간접적으로 데이터베이스의 데이터를 다룰 수 있게 해 Persistence API라고도 한다. 이렇게 우리는 ORM을 통해 SQL 문을 직접 작성하지 않고도 엔티티를 객체로 표현하고 다룰 수 있는 것이다.

예시
간단히 예를 들자면, Member 테이블의 데이터를 출력하기 위해서 MySQL에서는 SELECT*FROM Member 라는 쿼리를 실행해야 하지만, ORM(ex. Spring Data JPA)을 사용하면 JpaRepository를 상속받아 findAll() 라는 메서드 호출로 데이터 조회가 가능하다.

객체-관계 간의 불일치?




📌 ORM의 장단점

🙆‍♂️장점🙆‍♀️

  • 객체 지향적 코드로 인해 더 직관적
    : ORM을 이용하면 SQL Query가 아닌 코드(메서드)로 데이터를 조작할 수 있기에 더욱 직관적인 데다가, SQL의 절차적이고 순차적인 접근이 아닌 객체지향적 접근으로 인해 생산성도 증가한다.
  • 개발자가 비즈니스 로직에 더욱 집중
    : 위와 같은 맥락에서, 개발자가 SQL Query에 맞추려 하지 않아도 되고 객체 모델로 프로그래밍하는 데 집중할 수 있기에, 비즈니스 로직에 더 집중할 수 있다.
  • 재사용 및 유지보수가 편리
    : ORM은 독집적으로 작성할 수 있고, 해당 객체들은 재활용할 수 있기에 가공된 데이터를 컨트롤러를 통해 뷰로 합치는 디자인 패턴에 보다 유리하다.
  • DBMS에 대한 종속성이 줄어듦
    : 대부분 ORM 솔루션은 DB에 종속적이지 않다. 여기서 '종속적이지 않음'은, 구현 방법과 더불어 데이터 타입까지도 해당된다. 즉, 프로그래머는 DB가 아닌 Object에 집중할 수 있고, 극단적으로 DBMS를 교체하는 거대한 작업을 할 필요가 생겨도 비교적 적은 리스크와 시간으로 작업이 가능하다.
    (이는 전에 다룬 Spring / Spring Boot에서 "PSA"라는 특징을 설명한 내용과 같은 맥락이라 볼 수 있겠다.)

🙅‍♂️단점🙅‍♀️

  • 완벽한 ORM으로만 서비스를 구현하기 어려움
    : 사용하기엔 편리하나, 잘못 구현할 경우 오류에 대한 파장이 비교적 크기에 설계는 매우 신중하게 해야 한다.
  • 프로시저가 많은 시스템에선 ORM의 객체 지향적인 장점을 활용하기 어려움
    : 이미 프로시저가 많은 시스템에선 다시 객체로 바꾸어야 하며, 그 과정에서 생산성 저하나 리스크가 많이 발생할 수 있다.
    *프로시저(Procedure) : 일련의 쿼리를 마치 하나의 함수처럼 실행하기 위한 쿼리의 집합



📌 ORM 프레임워크들

JPA/Hibernate

JPA(Java Persistence API)는 자바의 ORM 기술 표준으로 인터페이스의 모음이다. 이러한 JPA 표준 명세를 구현한 구현체가 바로 Hibernate이다.

Sequelize

Sequelize는 Postgres, MySQL, MariaDB, SQLite 등을 지원하는 Promise에 기반한 비동기로 동작하는 Node.js ORM이다.

Django ORM

이는 Python 기반 프레임워크인 Django에서 자체적으로 지원하는 ORM이다.

0개의 댓글