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는 모두 접근 가능하게 해준다.
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
에서 이렇게 불러온다. 이런식으로 작성하니 코
드가 매우 깔끔해진 것을 볼 수 있다.
"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-extension
은 app.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
파일을 이렇게 작성하여 최상단에 위치시켜주면 된다.