1. [DataBase] TypeORM & DB
이전 Express를 이용한 초기환경세팅과 .gitignore를 사용하는 방법을 알려드렸습니다.
이번에는 이어서 TypeORM과 TypeORM을 활용해 DB를 연결하는 방법을 알려드리겠습니다.
이전 내용을 못보셨다면 아래 링크를 통해 먼저 참고해주세요.
2023.11.03 - [BackEnd] - [Node] Express를 이용해 API 서버 만드는 방법 1
🔵 ORM 이란?
ORM(Object-relational mapping)은 객체지향 프로그래밍(Object-Oriented-Programming)과 관계형 데이터베이스(Relational-Database)사이의 호환되지 않는 데이터를 변환하는 기술입니다. 즉, ORM은 이렇게 서로 다른 객체와 관계형 데이터 시스템(RDBMS)을 연결해주는 중간 매개체 역할을 합니다.
ORM은 관계형 데이터베이스의 2차원 테이블과 테이블 안에 저장된 행(data)을 애플리케이션의 Class와 인스턴스에 각각 매핑해주는 역할을 합니다. 이런 특징으로 애플리케이션에서 프로그래밍 언어만을 사용하여 선언한 Class와 Instance등으로 명령을 내리기에는 서로 연관성이 없어보였던 데이터베이스 내부 자료 속성에 접근할 수 있게 되었습니다.
🔵 ORM 사용 장점
ORM 사용 장점은 선언문, 할당, 종료 등과 같은 부수적인 코드가 사라짐으로 개발의 생산성이 향상됩니다. 그리고 문법 실수 없이 잘 짜여진 SQL 쿼리문을 ORM의 힘을 빌려 사용해 버그와 실수가 감소하게 되며, 개발자 친화적인 간결하고 직관적인 코드 작성이 가능해집니다. 이로써 가독성도 높아지는 효과를 누릴 수 있습니다.
대부분 ORM 서비스는 특정 RDBMS(ex. MySQL)에만 종속되는 것이 아닌 다양한 DB에 유연하게 연결 될 수 있습니다.
개발자는 어떤 데이터베이스 시스템을 선택했는지 상관없이 코드 속 다루어야 하는 데이터 객체 위주로 집중할 수 있는 이점이 존재합니다.
🔵 ORM 사용 단점
이런 ORM의 단점은 미세한 수정 및 디버깅(컴퓨터 프로그램 개발 단계 중 발생하는 시스템의 논리적 오류나 비정상적 연산을 찾아내고 수정하는 작업 과정)이 상대적으로 어려워지며, 복잡한 쿼리문 작성이 필요할 때 ORM에서 미리 선언해 놓은 패턴에 따른 SQL 쿼리 명령만 내릴 수 있는 점입니다. 이런 점은 내가 의도한 목표치에 가장 가까운 지름길이 아닌 먼 길을 돌아가야 하는 경우가 생길 수도 있습니다.
DB에 직접 명령을 내리지 않고 한 단계 중간 단계를 거쳐가기 때문에 SQL Raw 쿼리문에 비해 실행 속도가 다소 느려질 수 있으며 ORM은 데이터베이스 드라이버(mysqlclient, mysql2)를 한번 추상화(드라이버와 ORM 사이에 중간 수준)하고 이를 다시 한 번 추상화하는 고수준의 추상화 개념이 적용되기 때문입니다.
이런 단점 외에도 RDBMS와 데이터 관련 상호작용 내역을 Black Box(외부에서 쉽게 확인할 수 없게 숨기는 기능)로 만들어 버려 내부에 실제 어떤 쿼리를 실행하는지 파악하기 쉽지 않습니다. 그리고 경우에 따라 2차원 테이블 레코드를 1건만 읽어도 될 쿼리를 불필요하게 수 천, 수만 레코드를 읽어 과도하게 많은 쿼리를 생성하는 경우도 발생할 수 있습니다.
🔵 SQL Raw Query > ORM
앞으로의 DB 연결 방법은 ORM이 아닌 TypeORM에서 제공하는 데이터베이스 연결(풀링)기능과 Raw Query만 사용할 예정입니다.
Why?
- 데이터베이스와 Connection만 사용해서 직접 SQL 쿼리문을 작성하게 되면, 내가 의도한 데이터 테이블이 어떤 원리로 기능하는지 본연의 작동 원리를 이해
- 특정 ORM학습에 오랜 시간을 들여 익히면 다른 ORM을 사용시 또 다시 처음부터 익혀야 하는 비용이 발생하지만 모든 ORM의 근간인 SQL 문을 완벽하게 이해한다면 다른 ORM 도입 시에도 그 진입장벽이 한층 낮아짐
- 복잡한 쿼리를 사용하는 경우 ORM은 비효율적이며 고차원의 추상화 과정을 거친 시스템 특성상 성능 저하 이슈 발생
- ORM은 만능 열쇠가 아니며 우리가 의도하고자 하지만 ORM으로 표현 하지 못하는 쿼리가 존재
🔵 TypeORM 개념
Node와 RDBMS의 ORM 서비스에 많은 라이브러리들이 시중에 출시 되었으며. 그 중 개발자들이 가장 애용하는 상위 3개 라이브러리는 sequelize, typeorm, prisma 입니다.
Javascript 뿐 아닌 Typescript와의 호환에도 용이한 확정성에 유리한 TypeORM을 채택해 DB를 연결할 예정입니다.
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을 사용하는데 있어 다양한 환경 변수 설정법이 존재합니다. 그 중 .env 파일 내부에 다양한 TypeORM 환경 변수 정보를 저장한 후 사용하는 방법을 대표예시로 보여드리겠습니다. 경우에 따라 여기서 적용한 환경변수 활용법이 언제든지 지원종료(deprecated)가 될 수 있습니다. 따라서 내가 자주 사용하는 모듈에 대해 주기적인 관심을 가지고 업데이트 로그를 활용하는 것이 좋습니다.
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를 사용할 수 있는 명령어 작성 후 typeORM에 DataSource 모듈을 불러옵니다. 과거 사용된 createConnection이라는 메소드는 이제 TypeORM에서 지원하지 않아(버전 0.3.0 부터 deprecated 되었음) 참고 부탁드립니다.
const dotenv = require("dotenv")
dotenv.config()
const { DataSource } = require('typeorm');
이후, .env 파일에 저장된 환경변수들을 불러와 DataSource 명령어를 통해 db와의 커넥션 환경 세팅을 완료합니다.
그리고 initialize() 메소드를 통해 실제 연결을 완료합니다.
아래 새롭게 언급된 process 객체는 node.js 에서 기본으로 설정되는 글로벌 객체로써 require 호출 없이 언제든 모든 모듈에 접근 가능한 객체입니다. 별도 설정없이 node 설치 후 init 및 run을 실행할 때 접근이 가능하며 node.js 프로그램의 런타임 환경과 관련된 다양한 정보들을 담고 있는 객체로 그 중 환경변수를 선언한 .env 객체에 접근해 우리가 원하는 TypeORM 관련 환경변수들으르 끌어올 수 있습니다.
Node.js에 대해 이전에 설명된 블로그가 있으니 참고해주세요.
2023.11.02 - [BackEnd] - Node.js에 대해 알아보기, Node.js 설치 방법
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의 성공적인 연동을 의미하는 콘솔 로그에 의도한 메시지가 서버단에 띄어지게 될 것입니다. [ local mysql의 env에 실제 존재하는 DB name을 넣으셔야 하며 DB password 또한 본인의 pw로 변경해야 하는 점 참고해주세요. ]
아래와 같이 manager 클래스에 접근해 query 메소드를 사용해 그 안에 내가 원하는 쿼리문을 작성하면 db와 정상적으로 연동 되었다는 가정하에 성공적으로 쿼리문이 실행됩니다.
const DataSource = myDataSource.query(`SELECT * FROM USERS`)
'BackEnd' 카테고리의 다른 글
[Node] Layered Pattern (0) | 2023.11.13 |
---|---|
API Architecture에 대해 (0) | 2023.11.12 |
[Node] Express를 이용해 API 서버 만드는 방법 1 (0) | 2023.11.03 |
[Node] Exrpess란, Express를 사용하는 이유 (0) | 2023.11.03 |
Node.js의 기능, Npm이란? (0) | 2023.11.03 |
댓글