[nodejs] - 10. nestjs에서 DB 연동하기

2024. 4. 30. 01:04cs및 소프트스킬/nodejs

728x90
반응형
SMALL

지난 시간에는 nestjs 셋팅 및 api 제작을 진행 해 보았다.

하지만, DB 연동 없이는 nestjs에서 사용된 기록을 저장이 없어 nestjs 서버 종료 시 데이터가 날라가는 현상이 발생을 하는 것이 단점이 된다.

 

따라서 nestjs와 Database를 연동하여 사용하고자 한다.

필자는 MySQL을 활용하여 Database 연동하여 사용하고자 한다.

 

 

Ver10 프로젝트!!

https://github.com/BerkleyLim/basic_nodejs

 

GitHub - BerkleyLim/basic_nodejs: 이 프로젝트는 node.js 입문을 위한 프로젝트 중 하나입니다.

이 프로젝트는 node.js 입문을 위한 프로젝트 중 하나입니다. Contribute to BerkleyLim/basic_nodejs development by creating an account on GitHub.

github.com

 

 

 

1. 필요한 ORM, Database 설치

- 필자는 typeorm과 mysql2를 이용하여 진행하고자 한다.

npm i --save @nestjs/typeorm typeorm mysql2 @nestjs/config

 

 

MAC 환경에서 설치시 mysql2가 에러가 발생할 수 있다., 즉 EACCES 에러 발생 할 경우 아래와 같이 명령어를 넣어주자.

npm i --save @nestjs/typeorm typeorm mysql2 @nestjs/config

 

 

 

2. 데이터베이스 설정

  - app.module.ts 파일에서 imports 할 모듈을 설정한다.

  - DB 정보 보호를 위해 하드코딩이 아닌 .env 파일에 저장하여 .env 파일에 설정한 DB 정보를 호출하여 사용한다.

 

<src/board/app.module.ts>

import { Module } from '@nestjs/common';
import { BoardModule } from './board/board.module';
import { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Board } from './board/entities/board.entity';

// 애플리케이션 루트 모듈, 각 모듀들은 이 파일에 import 함
@Module({
  imports: [
    ConfigModule.forRoot(), // config 모듈을 통한 process.env 객체 사용
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: process.env.DB_HOST,
      port: parseInt(process.env.PORT),
      username: process.env.DB_USER,
      password: process.env.DB_PASSWORD,
      database: process.env.NESTJS_PRAC1,
      entities: [Board], // Board entity 사용하기 위해 추가
      // entities: [__dirname + '/../**/*.entity{.ts,.js}'], // Board entity 사용하기 위해 추가
      synchronize: true, // 배포 환경에서는 false 사용
    }),
    BoardModule,
  ],
})
export class AppModule {}

 

 

 

3. .env 파일에 저장 방법

  - 사실 로컬, 개발, 운영 서버에 있는 DB 마다 각자 다르게 설정하여 지정하고, 배포시 Docker 형식이나 스크립트 설정하여 실행

DB_HOST=localhost
DB_USER=유저명
DB_PASSWORD=비밀번호
NESTJS_PRAC1=테이블명
PORT=포트명

 

 

 

4. board ORM을 사용할 Module 및 entity 설정

 

<src/board/board.module.ts>

import { Module } from '@nestjs/common';
import { BoardService } from './board.service';
import { BoardController } from './board.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Board } from './entities/board.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Board])],
  controllers: [BoardController],
  providers: [BoardService],
})
export class BoardModule {}

 

 

<src/board/entities/board.entity.ts>

- 아래는 ORM을 만들기 위해 실시

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

@Entity('board')
export class Board {
  @PrimaryGeneratedColumn()
  bno: number;

  @Column()
  // @Column({ type: 'varchar' })
  title: string;

  @Column()
  // @Column({ type: 'text' })
  contents: string;
}

 

 

 

 

5. Service 단 - DB 연동

import { Injectable } from '@nestjs/common';
import { CreateBoardDto } from './dto/create-board.dto';
import { UpdateBoardDto } from './dto/update-board.dto';
import { Board } from './entities/board.entity';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';

@Injectable()
export class BoardService {
  // private board: Array<Board> = [];
  // private bno = 0;
  constructor(
    @InjectRepository(Board)
    private boardRepository: Repository<Board>,
  ) {}

  /**
   * 다음은 게시판을 생성한다.
   * @param createBoardDto : dto 클래스
   */
  async create(createBoardDto: CreateBoardDto): Promise<void> {
    // this.board.push({ bno: ++this.bno, ...createBoardDto });
    await this.boardRepository.save(createBoardDto);
  }

  /**
   * 게시판 전체 출력
   */
  findAll(): Promise<Board[]> {
    // return [...this.board];
    return this.boardRepository.find();
  }

  /**
   * 다음은, 해당 게시판 인덱스 찾는다.
   * @param bno : 인덱스 번호
   */
  findOne(bno: number): Promise<Board | null> {
    // const found = this.board.find((b) => b.bno === bno);
    // if (!found) throw new NotFoundException();
    // return found;
    return this.boardRepository.findOne({
      where: { bno },
    });
  }

  /**
   * 다음은 게시판을 수정한다.
   * @param bno : 인덱스번호
   * @param updateBoardDto : 필요 dto
   */
  async update(bno: number, updateBoardDto: UpdateBoardDto): Promise<void> {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    // const found = this.board.find((b) => b.bno === bno);
    // this.remove(bno);
    // this.board.push({ ...found, ...updateBoardDto });
    await this.boardRepository.update(bno, updateBoardDto);
  }

  /**
   * 게시판 삭제
   * @param bno : 삭제할 게시판 번호
   */
  async remove(bno: number): Promise<void> {
    // this.findOne(bno);
    // this.board = this.board.filter((b) => b.bno !== bno);
    await this.boardRepository.delete(bno);
  }
}

 

 

 

 

6. 연동 후 테스트

 

 

 

 

7. 마치며

  또 다른 Back-End의 기술 중 하나인 nodejs 를 익혔다. nodejs를 좀 더 효율적으로 짜기 위해 express.js 의 대한 기초를 걸치며 또 다른 툴인 nest.js 까지 익혀 Nest.js의 대한 ORM 까지 익힐 수 있는 기회가 되었다.

  아직은 고생길이 먼 길이지만 다양한 스택을 익혀 나만의 개발 실력을 만드는 것을 목적으로 둔다.

  추가적으로 프론트엔드 코드 까지 업로드 하였고 프론트엔드 개발은 아래와 같이 참조를 하는 것을 추천한다.

https://github.com/BerkleyLim/project_board

 

GitHub - BerkleyLim/project_board: Spring Boot + React CRUD형 게시판 만들기 프로젝트 안내서

Spring Boot + React CRUD형 게시판 만들기 프로젝트 안내서. Contribute to BerkleyLim/project_board development by creating an account on GitHub.

github.com

 

 

 

728x90
반응형
LIST