ORM 뜻, 설명, 장단점

2023. 3. 28. 23:37코딩/잡 공부

ORM 뜻, 설명, 장단점

 

  • ORM (Object Relational Mapping)

객체 지향적 구조 - 모든 데이터는 객체이며, 각 객체는 독립된 데이터와 독립된 함수를 지님
SQL 구조 - 데이터는 테이블 단위로 관리되며 객체들을 조회하기 위한 명령어를 사용
ORM - 각 테이블 또는 구분하고자 하는 데이터 단위로 객체를 구현하고, 데이터 간의 관계를 형성

 

  • 예시 - 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결)해주는 Framework
  1. Flask ORM - SQLAlchemy

SQLAlchemy를 통해 db라는 변수를 생성하였고, db.Model을 상속받아 User 클래스를 생성

User=> id(자동 생성, primary key), username(String), email(String)

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

    def __repr__(self):
        return '<User %r>' % self.username

Furthermore it provides a class called that is a declarative base which can be used to declare models:sqlalchemysqlalchemy.ormModel

>>> from db import db
>>> db.create_all()

db(SQLAlchemy)를 import 한 후 db.create_all() 함수를 이용하여 테이블과 데이터베이스를 생성

 

User(Model)을 import 하여 데이터를 생성

>>> from db import User
>>> admin = User(username='admin', email='admin@example.com')
>>> guest = User(username='guest', email='guest@example.com')

 

위의 코드를 실행하더라도 아직 데이터베이스에 저장된 것은 아니며 다음 코드를 실행하면 데이터베이스에 저장

 
>>> db.session.add(admin)
>>> db.session.add(guest)
>>> db.session.commit()​

 

데이터 쿼리

>>> User.query.all()
[<User u'admin'>, <User u'guest'>]
>>> User.query.filter_by(username='admin').first()
<User u'admin'>

<Model>.query.all() 함수를 이용하여 모든 데이터를 쿼리하면 아까 생성하였던 데이터가 출력됩니다.  또한 <Model>.query.filter_by() 함수를 이용하여 특정 데이터만 가져올 수도 있습니다.

(출력 방식은 User 클래스의 __repr__() 함수에서 정의한 형식으로 출력이 됩니다.)

 

 

 

 

2. Django ORM

3. Node.js ORM - Sequelize

4. JAVA ORM - JPA/Hibernate

JAVA

 
public class Person{
    private String name;
    private String height;
    private String weight;
    private String ssn;
    //implement getter & setter methods
}​

 

iBatis

 
<select id="getPerson" resultClass="net.agilejava.person.domain.Person">
    SELECT name, height, weight, ssn FROM USER WHERE name = #name#;
</select>​

해당 쿼리의 결과를 받을 객체를 지정해줄 수 있다. 즉, getPerson이라고 정의된 쿼리 결과는 net.agilejava.person.domain의 Person 객체에 자동으로 매핑 되는 것이다.

 

Hibernate

 
<hibernate-mapping>
    <class name="net.agilejava.person.domain.Person" table="person">
        <id name="name" column="name"/>
        <property name="height" column="height"/>
        <property name="weight" column="weight"/>
        <property name="ssn" column="ssn"/>
    <class>
</hibernate-mapping>GraphQL Schema ORM - Prisma​

위 두 개의 Framework의 예시를 보면 알 수 있듯이, setter 메소드가 있으면 객체에 결과를 set하는 작업을 따로 해주지 않아도 자동으로 해당 값이 할당된다. 물론 여기에 1:m 이나 m:1등의 관계들이 형성되면 추가적인 작업이 필요하긴 하지만, 일단 눈에 보이는 간단한 부분은 처리가 되는 것을 볼 수 있다. 물론 반대의 경우에도 객체를 던져주면 ORM Framework에서 알아서 get을 수행해 해당하는 column에 넣어주게 된다.

 

 

 

 

  • ORM 장점
  1. 위에서 언급했던 내용과 같이, 프로그래머는 DBMS에 대한 큰 고민 없이, ORM에 대한 이해 만으로 웬만한 CRUD를 다룰 수 있기 때문에, 로직에 집중할 수 있으므로 개발 생산성을 증가시킬 수 있다.
  2. 객체를 통하여 대부분의 데이터를 접근 및 수정을 진행하므로, 코드 가독성이 좋다.
  3. 데이터 구조 변경 시, 객체에 대한 변경만 이루어지면 되므로, 유지 보수성이 좋다. (매핑 정보가 명확하여, ERD를 보는 것에 대한 의존도를 낮출 수 있다.)

 

  • ORM 단점
  1. 복잡한 쿼리 작성시, ORM 사용에 대한 난이도가 급격히 증가한다.
  2. 호출 방식에 따라, 성능이 천차만별이다. 잘못 구현된 경우에 속도 저하 및 심각할 경우 일관성이 무너지는 문제점이 생길 수 있다.
  3. DBMS 고유의 기능을 전부 사용하지는 못한다.