# SQL (TypeORM)

## SQL (TypeORM)

### This chapter applies only to TypeScript

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

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

## Getting started

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

```bash
$ npm install --save typeorm mysql
```

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

```typescript
@@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` 접미사가 있는 별도의 파일로 사용자 지정 공급자를 선언했습니다.

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

```typescript
@@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](https://github.com/typeorm/typeorm)은 리포지토리 디자인 패턴을 지원하므로 각 엔터티에는 자체 리포지토리가 있습니다. 이 리포지토리는 데이터베이스 연결에서 얻을 수 있습니다.

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

```typescript
@@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`을 나타냅니다. 이제 **리포지토리** 공급자를 만들어 보겠습니다.

```typescript
@@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_REPOSITORY`와 `DATABASE_CONNECTION`은 분리 된 `constants.ts` 파일에 보관해야합니다.

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

```typescript
@@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`은 다음과 같습니다.

```typescript
@@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`로 가져 오는 것을 잊지 마십시오.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jakekwak.gitbook.io/nestjs/recipes/untitled.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
