데이터베이스를 연결하는 방법으로 이번엔 Postgres & TypeORM을 사용해 볼 것
https://www.enterprisedb.com/downloads/postgres-postgresql-downloads
NodeJS에서 실행되고 TypeScript로 작성된 객체 관게형 매퍼 라이브러리.
MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana 및 WebSQL과 같은 여러 데이터베이스를 지원함.
Object Relational Mapping
객체와 관계형 데이터베이스의 데이터를 자동으로 변형 및 연결하는 작업.
ORM을 이용한 개발은 객체와 데이터베이스의 변형에 유연하게 사용할 수 있습니다.
필요한 모듈
@nestjs/typeorm
: NEstJS에서 TypeORM을 사용하기 위해 연동시켜주는 모듈
typeorm
: TypeORM 모듈
pg
: Postgres 모듈
=>npm i pg typeorm @nestjs/typeorm --save
src/configs/typeorm.config.ts
config db 설정
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
export const typeORMConfig: TypeOrmModuleOptions = {
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: '',
database: 'board-app',
entities: [__dirname + '/../**/*.entity.{js,ts}'],
synchronize: true,
};
entities: [__dirname + '/../**/*.entity.{js,ts}']
가 제대로 작동하지 않아서, No metadata for "Board" was found 에러가 났다.
그래서entities: [Board]
로 바꾸어 주었더니 해결되었다.
src/app.module.ts
루트 모듈(app.module.ts)에서 import
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm/dist';
import { BoardsModule } from './boards/boards.module';
import { typeORMConfig } from './configs/typeorm.config';
@Module({
imports: [TypeOrmModule.forRoot(typeORMConfig), BoardsModule],
})
export class AppModule {}
forRoot안에 넣어준 설정은 모든 Sub_Module에 다 적용이 된다.
@Entity()
@Entity() 데코레이터 클래스는 Board 클래스가 엔티티임을 나타내는데 사용됨
@PrimaryGeneratedColumn()
여기서 id열이 Board 엔티티의 기본키 열임을 나타내는데 사용
@Column()
Board 엔티티의 title, description과 같은 기본 열을 나타내는데 사용
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { BoardStatus } from './board.model';
@Entity()
export class Board extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
description: string;
@Column()
status: BoardStatus;
}
리포지토리는 엔티티 개체와 함꼐 작동하며, 엔티티 찾기, 삽입, 업데이트, 삭제 등을 처리합니다.
데이터베이스와 관련된 일(INSERT, FIND, DELETE...)은 서비스에서 하는게 아닌 Repository에서 해주면 됩니다.
이것을 Repository Pattern이라고 합니다.
리포지토리 파일(board.repository.ts) 생성
생성한 파일에 리포지토리를 위한 클래스 생성
생성 시 Repository 클래스를 extends
=> find, insert, delete 등 엔티티를 컨트롤 할 수 있음.
@EntityRepository()
클래스를 사용자정의(Custom) 저장소로 선언하는데 사용
생성한 Repository를 다른곳에서도 사용하도록 boards.module.ts
에서 import
=> imports: [TypeOrmModule.forFeature([BoardRepository])],
board.repository.ts
typeorm 버전 0.3이상부터 EntityRepository가 없어짐
그래서 수정!
import { EntityRepository, Repository } from 'typeorm';
import { Board } from './board.entity';
@EntityRepository(Board)
export class BoardRepository extends Repository<Board> {}
=>
import { Injectable } from '@nestjs/common';
import { DataSource, Repository } from 'typeorm';
import { Board } from './board.entity';
@Injectable()
export class BoardRepository extends Repository<Board> {
constructor(private dataSource: DataSource) {
super(Board, dataSource.createEntityManager());
}
}
boards.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BoardRepository } from './board.repository';
import { BoardsController } from './boards.controller';
import { BoardsService } from './boards.service';
@Module({
imports: [TypeOrmModule.forFeature([BoardRepository])],
controllers: [BoardsController],
providers: [BoardsService],
})
export class BoardsModule {}
=>
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Board } from './board.entity';
import { BoardRepository } from './board.repository';
import { BoardsController } from './boards.controller';
import { BoardsService } from './boards.service';
@Module({
imports: [TypeOrmModule.forFeature([Board])],
controllers: [BoardsController],
providers: [BoardsService, BoardRepository],
})
export class BoardsModule {}