> For the complete documentation index, see [llms.txt](https://jakekwak.gitbook.io/nestjs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jakekwak.gitbook.io/nestjs/recipes/untitled-2.md).

# SQL (Sequelize)

## SQL (Sequelize)

### This chapter applies only to TypeScript

[Sequelize](https://github.com/sequelize/sequelize)는 바닐라 JavaScript로 작성된 인기있는 ORM (Object Relational Mapper)이지만 [sequelize-typescript](https://github.com/RobinBuschmann/%20sequelize-typescript)가 있습니다. 기본 시퀀스에 대한 데코레이터 및 기타 추가 세트를 제공하는 TypeScript 래퍼입니다.

## Getting started

이 라이브러리로 모험을 시작하려면 다음과 같은 종속성을 설치해야합니다.

```bash
$ npm install --save sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

우리가 해야 할 첫번째 단계는 생성자에 전달된 옵션 객체로 **Sequelize** 인스턴스를 만드는 것입니다. 또한 모든 모델을 추가해야 합니다 (대안은 `modelPaths` 속성을 사용하는 것임) 및 데이터베이스 테이블 `sync()`를 사용해야합니다.

```typescript
@@filename(database.providers)
import { Sequelize } from 'sequelize-typescript';
import { Cat } from '../cats/cat.entity';

export const databaseProviders = [
  {
    provide: 'SEQUELIZE',
    useFactory: async () => {
      const sequelize = new Sequelize({
        dialect: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'password',
        database: 'nest',
      });
      sequelize.addModels([Cat]);
      await sequelize.sync();
      return sequelize;
    },
  },
];
```

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

그런 다음 응용 프로그램의 나머지 부분에 대해 액세스 할 수 있도록 이러한 공급자를 내 보내야합니다.

```typescript
import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

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

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

## Model injection

[Sequelize](https://github.com/sequelize/sequelize)에서 **Model**은 데이터베이스의 테이블을 정의합니다. 이 클래스의 인스턴스는 데이터베이스 행을 나타냅니다. 먼저 우리는 최소한 하나의 엔티티가 필요합니다.

```typescript
@@filename(cat.entity)
import { Table, Column, Model } from 'sequelize-typescript';

@Table
export class Cat extends Model<Cat> {
  @Column
  name: string;

  @Column
  age: number;

  @Column
  breed: string;
}
```

`Cat` 엔티티는 `cats` 디렉토리에 속합니다. 이 디렉토리는 `CatsModule`을 나타냅니다. 이제 **저장소** 공급자를 만들 차례입니다.

```typescript
@@filename(cats.providers)
import { Cat } from './cat.entity';

export const catsProviders = [
  {
    provide: 'CATS_REPOSITORY',
    useValue: Cat,
  },
];
```

> **힌트** 실제 응용 프로그램에서는 **매직 문자열**을 피해야 합니다. `CATS_REPOSITORY`와 `SEQUELIZE`는 모두 분리 된 `constants.ts` 파일에 보관해야 합니다.

Sequelize에서는 정적 메서드를 사용하여 데이터를 조작하므로 여기에 **별명(alias)**&#xC744; 만들었습니다.

이제 `@Inject()`데코레이터를 사용하여 `CATS_REPOSITORY`를 `CatsService`에 삽입할 수 있습니다.

```typescript
@@filename(cats.service)
import { Injectable, Inject } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { Cat } from './cat.entity';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CATS_REPOSITORY') private readonly CATS_REPOSITORY: typeof Cat) {}

  async findAll(): Promise<Cat[]> {
    return await this.CATS_REPOSITORY.findAll<Cat>();
  }
}
```

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

마지막`CatsModule`은 다음과 같습니다.

```typescript
@@filename(cats.module)
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> warning **힌트** `CatsModule`을 루트 `ApplicationModule`로 가져 오는 것을 잊지 마십시오.
