SQL (TypeORM)

SQL (TypeORM)

This chapter applies only to TypeScript

경고 이 기사에서는 커스텀 프로 바이더 메커니즘을 사용하여 TypeORM 패키지를 기반으로 DatabaseModule을 작성하는 방법에 대해 설명합니다. 결과적으로 이 솔루션에는 즉시 사용 가능한 전용 @nestjs/typeorm패키지를 사용하여 생략할 수 있는 많은 오버 헤드가 포함되어 있습니다. 자세한 내용은 [여기] (/techniques/sql)를 참조하십시오.

TypeORM은 node.js 세계에서 가장 성숙한 ORM (Object Relational Mapper)입니다. TypeScript로 작성되었으므로 Nest 프레임 워크에서 잘 작동합니다.

Getting started

이 라이브러리로 모험을 시작하려면 필요한 모든 종속성을 설치해야합니다.

$ npm install --save typeorm mysql

우리가 해야할 첫번째 단계는typeorm 패키지에서 가져온 createConnection()함수를 사용하여 데이터베이스와 연결하는 것입니다. createConnection()함수는 Promise를 반환하므로 async provider를 만들어야합니다.

@@filename(database.providers)
import { createConnection } from 'typeorm';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: async () => await createConnection({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [
          __dirname + '/../**/*.entity{.ts,.js}',
      ],
      synchronize: true,
    }),
  },
];

warning 힌트 모범 사례에 따라 * .providers.ts 접미사가 있는 별도의 파일로 사용자 지정 공급자를 선언했습니다.

그런 다음 나머지 응용 프로그램에 대해 액세스 가능하도록 이들 공급자를 내 보내야합니다.

@@filename(database.module)
import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}

이제 @Inject() 데코레이터를 사용하여 Connection 객체를 주입할 수 있습니다. Connection 비동기 제공자에 의존하는 각 클래스는 Promise가 해결될 때까지 기다립니다.

Repository pattern

TypeORM은 리포지토리 디자인 패턴을 지원하므로 각 엔터티에는 자체 리포지토리가 있습니다. 이 리포지토리는 데이터베이스 연결에서 얻을 수 있습니다.

그러나 첫째, 우리는 최소한 하나의 실체가 필요합니다. 공식 문서에서 Photo 엔티티를 재사용 할 것입니다.

@@filename(photo.entity)
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

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

  @Column('text')
  description: string;

  @Column()
  filename: string;

  @Column('int')
  views: number;

  @Column()
  isPublished: boolean;
}

Photo 엔티티는 photo 디렉토리에 속합니다. 이 디렉토리는 PhotoModule을 나타냅니다. 이제 리포지토리 공급자를 만들어 보겠습니다.

@@filename(photo.providers)
import { Connection, Repository } from 'typeorm';
import { Photo } from './photo.entity';

export const photoProviders = [
  {
    provide: 'PHOTO_REPOSITORY',
    useFactory: (connection: Connection) => connection.getRepository(Photo),
    inject: ['DATABASE_CONNECTION'],
  },
];

warning 알림 실제 응용 프로그램에서는 매직 문자열을 피해야합니다. PHOTO_REPOSITORYDATABASE_CONNECTION은 분리 된 constants.ts 파일에 보관해야합니다.

이제 @Inject() 데코레이터를 사용하여 Repository<Photo>PhotoService에 주입할 수 있습니다 :

@@filename(photo.service)
import { Injectable, Inject } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';

@Injectable()
export class PhotoService {
  constructor(
    @Inject('PHOTO_REPOSITORY')
    private readonly photoRepository: Repository<Photo>,
  ) {}

  async findAll(): Promise<Photo[]> {
    return await this.photoRepository.find();
  }
}

데이터베이스 연결은 비동기이지만 Nest는 최종 사용자가 이 프로세스를 완전히 볼 수 없도록 합니다. PhotoRepository는 db 연결을 기다리고 있으며, PhotoService는 저장소를 사용할 준비가 될 때까지 지연됩니다. 각 클래스가 인스턴스화되면 전체 응용 프로그램을 시작할 수 있습니다.

마지막 PhotoModule은 다음과 같습니다.

@@filename(photo.module)
import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { photoProviders } from './photo.providers';
import { PhotoService } from './photo.service';

@Module({
  imports: [DatabaseModule],
  providers: [
    ...photoProviders,
    PhotoService,
  ],
})
export class PhotoModule {}

warning 힌트 PhotoModule을 루트 ApplicationModule로 가져 오는 것을 잊지 마십시오.

Last updated