SQL (Sequelize)

SQL (Sequelize)

This chapter applies only to TypeScript

SequelizeλŠ” 바닐라 JavaScript둜 μž‘μ„±λœ μΈκΈ°μžˆλŠ” ORM (Object Relational Mapper)μ΄μ§€λ§Œ sequelize-typescriptκ°€ μžˆμŠ΅λ‹ˆλ‹€. κΈ°λ³Έ μ‹œν€€μŠ€μ— λŒ€ν•œ λ°μ½”λ ˆμ΄ν„° 및 기타 μΆ”κ°€ μ„ΈνŠΈλ₯Ό μ œκ³΅ν•˜λŠ” TypeScript λž˜νΌμž…λ‹ˆλ‹€.

Getting started

이 라이브러리둜 λͺ¨ν—˜μ„ μ‹œμž‘ν•˜λ €λ©΄ λ‹€μŒκ³Ό 같은 쒅속성을 μ„€μΉ˜ν•΄μ•Όν•©λ‹ˆλ‹€.

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

μš°λ¦¬κ°€ ν•΄μ•Ό ν•  첫번째 λ‹¨κ³„λŠ” μƒμ„±μžμ— μ „λ‹¬λœ μ˜΅μ…˜ 객체둜 Sequelize μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“œλŠ” κ²ƒμž…λ‹ˆλ‹€. λ˜ν•œ λͺ¨λ“  λͺ¨λΈμ„ μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€ (λŒ€μ•ˆμ€ modelPaths 속성을 μ‚¬μš©ν•˜λŠ” κ²ƒμž„) 및 λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ” sync()λ₯Ό μ‚¬μš©ν•΄μ•Όν•©λ‹ˆλ‹€.

@@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 접미사가 μžˆλŠ” λ³„λ„μ˜ 파일둜 μ‚¬μš©μž 지정 κ³΅κΈ‰μžλ₯Ό μ„ μ–Έν–ˆμŠ΅λ‹ˆλ‹€.

그런 λ‹€μŒ μ‘μš© ν”„λ‘œκ·Έλž¨μ˜ λ‚˜λ¨Έμ§€ 뢀뢄에 λŒ€ν•΄ μ•‘μ„ΈμŠ€ ν•  수 μžˆλ„λ‘ μ΄λŸ¬ν•œ κ³΅κΈ‰μžλ₯Ό λ‚΄ λ³΄λ‚΄μ•Όν•©λ‹ˆλ‹€.

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μ—μ„œ Model은 λ°μ΄ν„°λ² μ΄μŠ€μ˜ ν…Œμ΄λΈ”μ„ μ •μ˜ν•©λ‹ˆλ‹€. 이 클래슀의 μΈμŠ€ν„΄μŠ€λŠ” λ°μ΄ν„°λ² μ΄μŠ€ 행을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€. λ¨Όμ € μš°λ¦¬λŠ” μ΅œμ†Œν•œ ν•˜λ‚˜μ˜ μ—”ν‹°ν‹°κ°€ ν•„μš”ν•©λ‹ˆλ‹€.

@@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을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€. 이제 μ €μž₯μ†Œ κ³΅κΈ‰μžλ₯Ό λ§Œλ“€ μ°¨λ‘€μž…λ‹ˆλ‹€.

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

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

힌트 μ‹€μ œ μ‘μš© ν”„λ‘œκ·Έλž¨μ—μ„œλŠ” 맀직 λ¬Έμžμ—΄μ„ ν”Όν•΄μ•Ό ν•©λ‹ˆλ‹€. CATS_REPOSITORY와 SEQUELIZEλŠ” λͺ¨λ‘ 뢄리 된 constants.ts νŒŒμΌμ— 보관해야 ν•©λ‹ˆλ‹€.

Sequelizeμ—μ„œλŠ” 정적 λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터λ₯Ό μ‘°μž‘ν•˜λ―€λ‘œ 여기에 별λͺ…(alias)을 λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

이제 @Inject()λ°μ½”λ ˆμ΄ν„°λ₯Ό μ‚¬μš©ν•˜μ—¬ CATS_REPOSITORYλ₯Ό CatsService에 μ‚½μž…ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

@@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은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

@@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둜 κ°€μ Έ μ˜€λŠ” 것을 μžŠμ§€ λ§ˆμ‹­μ‹œμ˜€.

Last updated

Was this helpful?