nest๊ฐ์๋ฅผ ๋ณด๋ฉด ์ผ๋จ ์ธ๋ฉ๋ชจ๋ฆฌ๋ก ์ฝ๋๋ฅผ ์ง๋ค๊ฐ ๋์ค์ DB ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์๋ ค์ค๋ค. expressํ ๋๋ ๊ทธ๋ฅ ๋ฐ๋ก ์๋ ค์คฌ๋๋ฐ...์๊ฐํด๋ณด๋ฉด nest์์ DB๋ฅผ ์ฐ๊ฒฐํ๋๊ฒ ๋ณต์กํด์ ์๋๊น ์ถ๋ค.
์ฐ์ nest.js์์ DB์ฐ๊ฒฐํ ๋ ์ฝ๊ฒ ํด์ฃผ๋ orm์ ์ค์นํด๋ณด์.
window ๋ฒ์ ๊ธฐ์ค
npm i typeorm@0.3.0
npm i @nestjs/typeorm mysql
ํน์ ์ค์นํ ๋ class-validator๋๋ฌธ์ ์คํจํ๋ค๋ฉด class-validator๋ฅผ ์ง์ฐ๊ณ ๋์ค์ class-validator๋ฅผ ์ค์นํ๋๊ฒ๋ ๋ฐฉ๋ฒ์ด๋ค. ์๋ ๋ช ๋ น์ด๋ฅผ ์ฐจ๋ก๋๋ก ์คํํด๋ณด๋ฉด ๋ ๋ฏ.
npm uninstall class-validator
npm i typeorm@0.3.0
npm i @nestjs/typeorm mysql
npm i class-validator
.env
๋์ nest.js์์@nestjs/config
ํจํค์ง ์ฌ์ฉnpm i @nestjs/config
.env
ํ์ผ ์์ฑ ํ ๋ด์ฉ ์
๋ ฅDATABASE_HOST="localhost"
DATABASE_PORT=3306
DATABASE_USERNAME="์ฌ๋ฌ๋ถ๋ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ด๋"
DATABASE_PASSWORD="์ฌ๋ฌ๋ถ๋ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋น๋ฐ๋ฒํธ"
DATABASE_NAME="board"
DATABASE_SYNCHRONIZE=true
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { BoardModule } from "./board/board.module";
import { TypeOrmConfigService } from "./config/typeorm.config.service";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { Article } from "./board/article.entity";
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }), // ์ถ๊ฐ (์ฐธ๊ณ : ๋งจ ์๋ก ์์ผํจ)
TypeOrmModule.forRootAsync({ // ์ถ๊ฐ
imports: [ConfigModule],
useClass: TypeOrmConfigService,
inject: [ConfigService],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
import { Injectable } from "@nestjs/common";
import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from "@nestjs/typeorm";
import { ConfigService } from "@nestjs/config";
import { Article } from "src/board/article.entity";
@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 + "/**/*.entity{.ts,.js}"],
synchronize: this.configService.get<boolean>("DATABASE_SYNCHRONIZE"),
};
}
}
๊ธฐ์กด ํ ์ด๋ธ, ์คํค๋ง์ ๊ฒฝ์ฐ ๋ณ๋๋ก ์คํค๋ง๋ฅผ ๋ง๋ค์ด์ ๋นผ์คฌ์ง๋ง, nest์์๋ ๊ฐ ํด๋นํ๋ ํด๋ ๋ด์ ๊ฐ๊ฐ ๋ง๋ค์ด ์ฃผ๋๋ฏ. (์์๋ก board๊ด๋ จ entity๋ board ํด๋ ๋ด์ board.entity.ts๋ฅผ ์์ฑ, user์ ๊ด๋ จ๋ entity๋ userํด๋์ user.entity๋ฅผ ์์ฑ)
์ด๊ฑด cli๋ก ์ง์ํ์ง์๊ธฐ๋๋ฌธ์ ์ง์ ํด๋์ ํ์ผ ์์ฑ์ ํด์ค์ผํ๋ค.
์๋๋ article๊ณผ ๊ด๋ จ๋ ์์์ด๋ค.
// article.entity.ts
import {
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from "typeorm";
@Entity({ schema: "board", name: "articles" })
export class Article {
@PrimaryGeneratedColumn({ type: "int", name: "id" })
id: number;
@Column("varchar", { length: 10 })
author: string;
@Column("varchar", { length: 50 })
title: string;
@Column("varchar", { length: 1000 })
content: string;
@Column("varchar", { select: false })
password: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
@DeleteDateColumn()
deletedAt: Date | null;
}
nest์์ Repository๋ ๋๊ฐ์ง๋ก ๋๋๋ค.
1. ์ผ๋ฐ ๋ ํฌ์งํ ๋ฆฌ
2. ์ปค์คํ ๋ ํฌ์งํ ๋ฆฌ
constructor(
@InjectRepository(Article) private articleRepository: Repository<Article>
) {}
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { Article } from "./article.entity";
import { BoardController } from "./board.controller";
import { BoardService } from "./board.service";
@Module({
// โญโญโญ ์๋น์ค์์ ์ฌ์ฉํ ๋ฆฌํฌ์งํ ๋ฆฌ ์ฌ์ฉ์ imports์ ๋ฃ์ด์ฃผ๊ธฐ โญโญโญ
imports: [TypeOrmModule.forFeature([Article])],
controllers: [BoardController],
providers: [BoardService],
})
export class BoardModule {}