이번에는 TypeORM을 활용해서 NestJS와 MySQL 을 연결해보자
이전에 mongoose, MongoDB를 통해 스키마를 작성한것과 유사하다.
section08 폴더 내 08-02-nestjs-with-graphql 폴더에서 node_modules 와 dist 폴더를 삭제한 뒤, 복사하여 붙여 넣어서 이름을 08-04-nestjs-with-typeorm 으로 바꿔준다.
MongoDB 를 사용할 때는
model 파일로 표현하여 사용하는 반면,
표 형태의 SQL DB 같은 경우에는Entity 파일로 표현한다.
따라서, 직접 타입스크립트를 이용해서 Entity를 작성해보자
entity를 작성하기 이전에 TypeORM을 먼저 설치해서 연결해야한다.
TypeORM 설치 관련해서는 NestJS Docs → Techniques → Database 로 들어가서 확인해보자

yarn으로 설치하기 위해 아래의 명령어를 복사해 해당 폴더 터미널에 붙여넣기 한다.
$ yarn add @nestjs/typeorm typeorm mysql2
위 명령어를 통해 일반 TypeORM 과 NestJS 용 TypeORM 2가지를 모두 설치했다.
@nestjs/typeorm : NestJS 용 TypeORM.typeorm : typeorm 최신 버전으로 설치.mysql2 : TypeORM 을 MySQL 로 연결하기 위한 프로그램 설치.설치 후, TypeORM 셋팅에 대해서는 방금 전 확인한 Docs 아래쪽에 나와 있다.
Docs 를 확인하면서 TypeORM 을 연결시켜보자

mysql과 연결시켜주기 위해서 TypeOrmModule 의 옵션을 설정해야 한다.
src → app.module.ts 파일로 들어와 아래와 같이 작성해준다.
// app.module.ts
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BoardModule } from './apis/boards/boards.module';
import { Board } from './apis/boards/entities/board.entity';
@Module({
imports: [
BoardModule,
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: 'src/commons/graphql/schema.gql',
}),
TypeOrmModule.forRoot({
type: 'mysql', // 데이터 베이스 타입
host: 'localhost', // local 환경으로 진행
port: 3306, // mysql은 기본 port는 3306
username: 'root', // mysql은 기본 user는 root로 지정
password: 'root', // 본인의 mysql password
database: 'myproject', // 연결할 데이터 베이스명
entities: [Board], // 데이터 베이스와 연결할 entity
synchronize: true, // entity 테이블을 데이터베이스와 동기화할 것인지
logging: true, // 콘솔 창에 log를 표시할 것인지
}),
],
})
export class AppModule {}
myproject 라는 이름의 데이터베이스를 생성해줘야 정상적으로 작동한다.src → apis → boards → entities 폴더를 만들고, entities 폴더 안에서 board.entity.ts 파일을 만든다.
board.entity.ts 파일을 아래와 같이 작성해준다.
// board.entity.ts
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Board {
@PrimaryGeneratedColumn('increment')
number: number;
@Column()
writer: string;
@Column()
title: string;
@Column()
contents: string;
}
@Entity : Board class가 실행될 때, typeorm에 의해 Entity 테이블 생성해준다.@PrimaryGeneratedColumn : 자동으로 생성될 값의 컬럼이다. 속성값에 따라 달라짐increment : 데이터가 한 줄씩 쌓일 때마다 자동으로 숫자가 1씩 증가하여 값이 생성된다.uuid : 중복되지 않는 문자열 ID가 자동으로 생성된다.@Column : 표 형태에서 열 에 해당. 실제 들어갈 데이터의 값의 컬럼이다.데이터베이스를 연결시켜서 데이터베이스 표 안에 우리가 만든 Entity가 실제로 들어오는지 확인해 보자
NestJS를 실행시키는 순간 Board entity를 읽게 되고 synchronize 로 인해 Board entity 테이블과 dbeaver 가 동기화되어 Dbeaver 안에 Board 테이블이 자동으로 생성되게 되는 구조다.
따라서, DBeaver를 통해서 MySQL을 연결시켜 보겠다.
MySQL을 열어서 확인해 볼 수 있는 도구인 DBeaver 를 열어주고
이전에 만들어 둔 mysql 내 Databases를 우클릭해 Create New Database를 눌러준다.

app.module.ts 파일에 작성한 database 이름과 동일한 이름으로 database를 만들어 준다.

그리고 VSCode 해당 폴더 터미널에서 yarn start:dev 명령어를 통해 NestJS를 실행한다.
아래와 같이 나타난다면 성공적으로 실행된 것이다.

터미널을 확인해보면 Query문을 통해 DB가 만들어진 것까지 확인할 수 있다.

서버를 켰을 때, 아래와 같은 error가 발생한다면?
- Error 내용
Error : Unknown database ‘ DB 이름
- 해결방법
DBeaver에서 database를 만들어 주지 않았거나,
app.module.ts파일에 작성한 database 이름과 DBeaver에 만들어 준 database 이름이 달라서 발생하는 에러이기 때문에 DBeaver에 database를 만들고 이름이 동일한지 확인해야한다.
서버를 켰을 때, 아래와 같은 error가 발생한다면?
- Error 내용 ( 아래 두 error 중 1개라도 포함될 경우 )
Error : Error connect ECONNREFUSED 127.0.0.1:3306
Error : Access denied for user 'root'@'localhost’- 해결방법
- Mac 사용자
터미널에서brew services start mysql명령어를 입력하고, 다시 dbeaver로 접속을 시도해 볼것- Ubuntu 사용자
터미널에서sudo systemctl start mysql명령어를 입력하고, 다시 dbeaver로 접속을 시도해 볼것
이제 다시 DBeaver 로 돌아가서 확인해보도록 하겠습니다.
Databases를 더블 클릭하면 myproject 데이터 베이스 안에 board 테이블이 생성된 것을 확인할 수 있다.
만약 board 테이블이 보이지 않는다면, Databases 우클릭하여 새로고침을 눌러준다.
board 테이블을 클릭하여 Data 를 보면 표가 만들어져 있는것을 확인할 수 있다.

추후, 엔티티 코드 수정을 하게 되면 DBeaver 해당 데이터베이스를
새로고침해줘야만 자동 반영된다.
앞서 MongoDB 를 사용할 때는 접속 명령어 mongo를 통해 접속하고 show collections 등의 여러 명령어를 통해 데이터를 확인하였다. 이것을 CLI(Command Line Interface) 라고한다.
지금 배우고 있는 MySQL 또한 CLI(Command Line Interface) 로써, 명령어를 통해 접속하고 show tables 등과 같은 명령어로 테이블 생성, 데이터 생성, 데이터 조회 등을 할 수 있습니다. 이것을 SQL Query문 이라고 한다.
하지만, 명령어를 모두 외워서 데이터를 보는 건 쉽지 않다. 따라서 데이터를 쉽게 볼 수 있는 GUI 도구(관리프로그램)가 존재합니다.
이전에 사용한 MongoDB compass 와 DBeaver 가 GUI 도구이며, 이를 이용해서 객체 형태, 표 형태로 보고 싶은 대로 데이터를 볼 수 있다. MongoDB compass, DBeaver 뿐만 아니라 다른 대체 프로그램들도 많이 존재한다.
옛날에는 명령어를 가지고 Board 테이블을 직접 만들었지만
지금까지 명령어를 통해서 하나하나 만든 것이 아니라 자동으로 table이 생성 된것을 실습을 통해 확인했다.
MongoDB 에서는 Boards.save() 등을 통해 데이터 저장 기능 뿐 아니라, 데이터를 만들거나 꺼내오는 것들이 가능했다.
이것을 ODM(Object Data Mapping)이라고 하며 몽구스를 사용했기 때문에 ODM 이 가능했다.
MySQL에서도 Boards.save() 로 데이터 저장 등이 가능한데, TypeORM을 사용하여 ORM이 가능하였기 때문이다.
코드를 실습해보면서 자동으로 데이터가 생성되는 것처럼 보이지만,
.save 등과 같은 내용을 바탕으로 TypeORM을 통해 SQL Query문으로 자동으로 변경되고 MySQL에 전달되면서 데이터가 생성된 것이다.
이렇게 TypeORM을 통해 SQL Query문으로 만들어져셔 보이는 것을 logging이라고 한다.
서버 실행 시 터미널에서 확인 가능하다.
또한, snchronize 는 Entity 와 MySQL DB에 있는 실제 저장된 컬럼들이 서로 같게 동기화 시켜주는것 이다.
이렇게 직접 쿼리문을 써야 하는 불편함이 적어지고 자동화되었지만, 그렇다고 SQL Query문을 몰라도 된다는 것은 아니다.
현재는 ORM을 중심으로 쓰고 있지만 ORM에서 커버가 되지 않는 부분은 직접 쿼리문을 사용해야 할때도 있다. ODM도 마찬가지다.
SQL Query문에 대해서는 이후 실제로 DB를 다루게 될때 자세히 배워보자
ODM & ORM
- ODM ( Object Document Mapping )
: NoSQL에서 Document Database를 지원하기 위해 데이터를 변환하는 프로그래밍 기법- ORM ( Object Relational Mapping )
: 데이터베이스와 객체 지향 프로그래밍 언어 간의 호환되지 않는 데이터를 변환하는 프로그래밍 기법