TypeORM & DB connection

류예린·2022년 8월 3일
1
post-custom-banner

1. ORM 개념 정리


✅ ORM의 개념

ORM(Object-relational mapping)은 객체지향 프로그래밍(Object-Oriented-Programming)과 관계형 데이터베이스(Relational-Database)사이의 호환되지 않는 데이터를 변환하는 기술이다. 즉, ORM은 이렇게 서로 다른 객체와 관계형 데이터 시스템(RDBMS)을 연결해주는 중간 매개체 역할을 한다.

ORM은 관계형 데이터베이스의 2차원 테이블과 테이블 안에 저장된 행(data)을 애플리케이션의 Class와 인스턴스에 각각 매핑해주는 역할을 한다. 이러한 특징 덕분에 애플리케이션에서 프로그래밍 언어(e.g. javascript)만을 사용하여 선언한 Class와 Instance등으로 명령을 내리기에는 서로 연관성이 없어보였던 데이터베이스 내부 자료 속성에 접근할 수 있다.

✅ ORM 사용의 장점

ORM을 사용하며 생기는 장점은 선언문, 할당, 종료 등과 같은 부수적인 코드가 사라짐으로써 개발의 생산성이 향상된다는 점이다. 그리고 문법(Syntax) 실수 없이 잘 짜여진 SQL 쿼리문을 ORM의 힘을 빌려 사용하는 것이기 때문에 버그와 실수가 감소하게 되며, 개발자 친화적인 간결하고 직관적인 코드작성이 가능해진다. 이로써 가독성 또한 높아지는 효과를 누릴 수 있다.

그리고 대부분의 ORM 서비스는 특정 RDBMS(예시; mysql)에만 종속되는 것이 아니라 다양한 데이터베이스에 유연하게 연결 될 수 있습니다. 따라서 개발자는 어떠한 데이터베이스 시스템을 선택했는지 상관없이 코드 속에서 다루어야 하는 데이터 객체 위주로 집중할 수 있는 이점이 있다.

✅ ORM 사용의 단점

하지만 이런 ORM도 사용에 있어서 물론 단점이 존재한다. 미세한 수정 및 디버깅이 상대적으로 어려워지며, 복잡한 쿼리문 작성이 필요할 때는 ORM에서 미리 선언해 놓은 패턴에 따른 SQL 쿼리 명령만 내릴 수 있다는 점이다. 따라서 내가 의도한 목표치에 가장 가까운 지름길이 아닌 먼 길을 돌아가야하는 경우가 생길 수 있다.

아울러, DB에 직접 명령을 내리지 않고 한단계 중간 단계를 거쳐가기 때문에 SQL Raw 쿼리문에 비해 실행 속도가 다소 느려질 수 있다. 왜냐하면 ORM은 데이터베이스 드라이버(mysqlclient, mysql2)를 한번 추상화(드라이버와 ORM 사이에 중간 수준)하고 이를 다시 한 번 추상화하는 고수준의 추상화 개념이 적용되기 때문이다.

이밖에도, RDBMS와의 데이터 관련 상호작용 내역을 Black Box(외부에서 쉽게 확인할 수 없게 숨기는 기능)로 만들어 버리기 때문에 내부에서 실제 어떤 쿼리를 실행하는지 파악하기 쉽지 않다. 그리고 경우에 따라서 2차원 테이블의 레코드를 1건만 읽어도 될 쿼리를 불필요하게 수 천, 수 만 레코드를 읽게하여 과도하게 많은 쿼리를 생성하는 경우도 발생할 수 있다.

✅ SQL Raw Query > ORM

앞으로 ORM을 사용하지 않고 TypeORM에서 제공하는 데이터베이스 연결(풀링) 기능과 Raw Query만 사용하며 학습을 진행할 예정이다. 이에 대한 상세한 이유는 다음과 같다.

  • 데이터베이스와 컨넥션만 사용해서 직접 SQL 쿼리문을 작성하게되면, 내가 의도한 데이터 테이블이 어떠한 원리로 기능하는지 그 본연의 작동 원리를 이해하는데 용이하다.
  • 특정 ORM 학습에 오랜 시간을 들여서 익히게되면, 다른 ORM 사용할 때 또 다시 처음부터 익혀야하는 비용이 발생하게 됩된다. 하지만 모든 ORM의 근간인 SQL문을 완벽히 이해가 되면 다른 ORM을 도입할 때 그 진입장벽이 한층 낮아지게 된다.
  • 복잡한 쿼리를 사용하는 경우 ORM은 비효율적일 수 있고, 고차원의 추상화 과정을 거친 시스템 특성상 성능 저하 이슈가 있을 수 있다.
  • ORM은 만능 열쇠가 아니다. 우리가 의도하고자 하지만 ORM으로 표현 못 하는 쿼리가 존재한다.





2. TypeORM 개념 및 사용법


✅ TypeORM

Node와 RDBMS의 ORM 서비스에는 많은 라이브러리들이 시중에 출시 되었으며, 그 중 개발자들이 가장 애용하는 상위 3개 라이브러리는 sequelizetypeormprisma 다.

저희는 Javascript 뿐만 아니라 Typescript 와의 호환에도 용이한, 보다 확장성에 유리한 TypeORM을 채택하여 학습을 진행하고 있다. 아울러 TypeORM에서 제공하는 다양한 ORM 기능에만 의존하지않고, mysql과 연결하여 직접 작성한 SQL Raw Query 문을 실행할 수 있게 DB 커넥터의 기능만을 활용하여 TypeORM을 사용하고 있다.

✅ TypeORM 설치

아래의 명령어를 이용해 TypeORM을 설치한다.

$ npm install typeorm      
# typeorm 설치 명령어

이 때, 새로 다운 받은 패키지간 버전 호환 문제로 다양한 에러가 발생할 수 있는데, 그 중 TypeORM - Mysql 사이의 연동을 도와주는 mysql driver가 존재하지 않는다는(missing) 에러가 날 경우에는 npm 을 경유하여 mysql 혹은 mysql2로 관련 드라이버를 재설치 해야 한다.

해당 절차를 따랐음에도 계속 문제가 발생한다면 설치시 내부 node_modules 구조가 설치 과정중 꼬여있을 수도 있음으로, TypeORM 삭제 → mysql/mysql2 설치 → TypeORM 드라이버 재설치 절차대로 다시 설치 과정을 진행해 준다.

$ npm uninstall typeorm    # typeorm 삭제 명령어
$ npm install mysql        # mysql 설치 명령어
$ npm install mysql2       # mysql2 설치 명령어

✅ Dotenv 파일(.env) 내 환경변수 설정법

TypeORM을 사용하는데 있어서 경우에 따라 내가 적용한 환경변수 활용법이 언제든지 지원 종료가 (deprecated) 될 수 있습니다. 앞으로 사용할 .env 또한 그렇다. 따라서 내가 자주 사용하는 모듈에 대해 주기적인 관심을 가지고 업데이트 로그를 확인 하는 것이 개발자의 기본 자세다.

TYPEORM_CONNECTION = mysql
TYPEORM_HOST = 127.0.0.1
TYPEORM_USERNAME = root
TYPEORM_PASSWORD = myPassword
TYPEORM_DATABASE = myDB
TYPEORM_PORT = 3306
TYPEORM_LOGGING =TRUE

이 밖에 다양한 환경변수 설정법에 대한 확인이 필요하다면 다음의 링크를 확인.

✅ TypeORM - Database 연결

먼저 아래 과 같이 dotenv를 사용할 수 있게 다음의 명령어를 작성한 후,

const dotenv = require("dotenv")
dotenv.config()

다음과 같이 typeorm을 DataSource 모듈을 불러온다. 과거 사용되었던 createConnection 이라는 메소드는 더이상 TypeORM에서 지원하지 않으므로(버전 0.3.0 부터 deprecated 되었음) 참고한다.

const { DataSource } = require('typeorm');

이후, .env 파일에 저장해놓은 환경 변수들을 불러와 DataSource 명령어를 통해서 db와의 커넥션 환경 세팅을 완료한다. 그리고 initialize() 메소드를 통해 실제 연결을 완료한다.

아래 새롭게 언급된 process 객체는 node.js 에서 기본으로 설정되는 글로벌 객체로써 별도의 require 호출 없이 언제, 어디서든지 모든 모듈에서 접근이 가능한 객체다. 별도의 설정없이 node 설치 후, init 및 run 을 실행할 때 접근이 가능하며 node.js 프로그램의 런타임 환경과 관련된 다양한 정보들을 담고 있는 객체다. 그 중 우리는 환경 변수를 선언한 env 객체에 접근하여 우리가 원하는 TYPEORM 관련 환경 변수들을 끌어올 수 있다.

const myDataSource = new DataSource({
    type: process.env.TYPEORM_CONNECTION,
    host: process.env.TYPEORM_HOST,
    port: process.env.TYPEORM_PORT,
    username: process.env.TYPEORM_USERNAME,
    password: process.env.TYPEORM_PASSWORD,
    database: process.env.TYPEORM_DATABASE
})

myDataSource.initialize()
    .then(() => {
        console.log("Data Source has been initialized!")
    })

위 내용이 정상적으로 작동되면 아래와 같이 datasource의 성공적인 연동을 의미하는, 콘솔 로그에서 의도한 메세지가 서버단에 출력된다.

[그림1] 런서버 정상 작동 성공

아래와 같이 manager 클래스에 접근하여 query 메소드를 사용하여 그 안에 내가 원하는 쿼리문을 작성하면 db와 정상적으로 연동이 되었다는 가정하에 성공적으로 쿼리문이 실행된다.

const DataSource = myDataSource.query(`SELECT * FROM USERS`)






3. 정리


  • ORM은 관계형 데이터베이스의 2차원 테이블과 테이블 안에 저장된 행(data)을 애플리케이션의 Class와 인스턴스에 각각 매핑해주는 기술이다.
  • ORM이 이러한 중간 매개체 역할을 할 때 다양한 장단점이 존재한다.
    • 장점: 개발의 생산성이 향상, 버그 및 실수 감소, 가독성 상승, 객체 지향적 접근 가능
    • 단점: 미세한 수정 및 디버깅시 난항, ORM이 지정해 놓은 명령만 수행 가능, 쿼리 수행 속도 저하
  • ORM 보다 SQL Raw Query 문을 이용하여 앞으로의 다양한 프로젝트를 진행할 예정이다. 이때, TypeORM의 db Connection 기능만을 빌려 사용한다.
profile
helloworld
post-custom-banner

0개의 댓글