nest.js와 mysql연동하기

0

Docker로 mysql 띄우기

docker run --name [db_name] -e MYSQL_ROOT_PASSWORD=[db_password] -d -p 3306:3306 mysql:latest

mysql을 docker container로 띄운다.


docker exec -it commit-mysql-dev bash
mysql -u root -p

컨테이너에 접속하고, mysql에 들어준다.


create database commit_mysql_dev;

그리고 우리들이 사용할 데이터베이스를 생성해주자.


ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password by 'yourpassword';
FLUSH PRIVILEGES;

이렇게 작성해주어서 외부 접속에서 root는 모두 접근 가능하게 해준다.


nestjs와 mysql 연동

npm i typeorm @nestjs/typeorm typeorm-extension mysql2

연동하기 위한 라이브러리들을 설치해주자.


import { Column, Entity, PrimaryColumn } from 'typeorm';

@Entity('User')
export class UserEntity {
  @PrimaryColumn()
  id: string;

  @Column({ length: 30 })
  name: string;

  @Column({ length: 60 })
  email: string;

  @Column({ length: 30 })
  password: string;

  @Column({ length: 60 })
  signupVerifyToken: string;
}

src/entities/user.entity.ts 파일에
UserEntity를 생성한다.


TypeOrmModule.forRoot({
  type: 'mysql',
  host: process.env.DATABASE_HOST,
  port: parseInt(process.env.DATABASE_PORT),
  username: process.env.DATABASE_USERNAME,
  password: process.env.DATABASE_PASSWORD,
  database: process.env.DATABASE_NAME,
  entities: [__dirname + '/entities/*.entity{.ts,.js}'],
  synchronize: false,
  logging: true,
}),

app.module.ts 의 imports에 추가한다.

하지만 이렇게 app.module.ts 에 DB의 모든 정보를 담아서 작성하는 방식은 나중에 redis 나 다른 연결 요소가 들어왔을때 최상단의 app.module.ts 가 매우 복잡해 질 수 있다.


import { Injectable } from '@nestjs/common';
import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class TypeormConfigService implements TypeOrmOptionsFactory {
  constructor(private readonly configService: ConfigService) {}

  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      host: this.configService.get<string>('DATABASE_HOST'),
      port: this.configService.get<number>('DATABASE_PORT'),
      username: this.configService.get<string>('DATABASE_USERNAME'),
      password: this.configService.get<string>('DATABASE_PASSWORD'),
      database: this.configService.get<string>('DATABASE_NAME'),
      entities: [__dirname + '/entities/*.entity{.ts,.js}'],
      synchronize: false,
      logging: true,
    };
  }
}

따라서 typeorm.config.service.ts 파일을 config폴더에 작성한다.


TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useClass: TypeormConfigService,
})

그 다음, app.module.ts 에서 이렇게 불러온다. 이런식으로 작성하니 코
드가 매우 깔끔해진 것을 볼 수 있다.


typeorm-extension

"db:create:dev": "NODE_ENV=development ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:create -d ./dataSource.ts",
"db:drop:dev": "NODE_ENV=development ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:drop -d ./dataSource.ts",
"schema:drop:dev": "NODE_ENV=development ts-node ./node_modules/typeorm/cli.js schema:drop -d ./dataSource.ts",
"schema:sync:dev": "NODE_ENV=development ts-node ./node_modules/typeorm/cli.js schema:sync -d ./dataSource.ts",
"db:create:prod": "NODE_ENV=production ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:create -d ./dataSource.ts",
"db:drop:prod": "NODE_ENV=production ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:drop -d ./dataSource.ts",
"schema:drop:prod": "NODE_ENV=production ts-node ./node_modules/typeorm/cli.js schema:drop -d ./dataSource.ts",
"schema:sync:prod": "NODE_ENV=production ts-node ./node_modules/typeorm/cli.js schema:sync -d ./dataSource.ts",

DB와 schema create/drop명령어 script를 작성해준다. 이때 typeorm-extension 이 사용되는데 typeorm-extensionapp.module.ts의 TypeOrmModule.forRoot를 읽지 못하기 때문에 dataSource.ts에 다시 작성해주고 파일 경로를 넘겨주어야 한다.


import { DataSource } from 'typeorm';
import dotenv from 'dotenv';

dotenv.config({
  path: `${__dirname}/src/config/env/.${process.env.NODE_ENV}.env`,
});

export const AppDataSource = new DataSource({
  type: 'mysql',
  host: process.env.DATABASE_HOST,
  port: parseInt(process.env.DATABASE_PORT),
  username: process.env.DATABASE_USERNAME,
  password: process.env.DATABASE_PASSWORD,
  database: process.env.DATABASE_NAME,
  entities: [__dirname + '/**/*.entity{.ts,.js}'],
  synchronize: false,
});

따라서 dataSource.ts 파일을 이렇게 작성하여 최상단에 위치시켜주면 된다.

profile
https://www.youtube.com/watch?v=__9qLP846JE

0개의 댓글

관련 채용 정보