NestJS 에서 여러 DB에 연결하기
NestJS : multiple database connection setup with TypeORM
  • Backend

시작하기에 앞서

이 글은 NestJS 프로젝트에서 어떻게 Multiple 로 Database에 연결하는지에 대해 설명한다.
개발하다보면 종종 MySQL 을 여러곳에 연결해야하는 경우가 생기곤 한다.

NestJS 공식문서를 참고하여 작성하였다.

DB 연결에 대한 설정

// module

...
@Module({
   imports: [
      TypeOrmModule.forRoot({
         type: 'mysql',
         host: 'localhost',
         port: 3306,
         username: 'root',
         password: 'root',
         database: 'test',
         entities: ['...'],
         synchronize: false,
      }),
   ],
})
...

NestJS 에서는 위와같이 Module의 imports에 TypeOrmModule.forRoot 를 사용하여 데이터베이스의 연결 정보를 설정할 수 있다.

여기서 Database 연결을 추가하고 싶으면 다음과 같이 추가해주면 된다.

...
@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...
      name: 'default',        
      host: 'localhost',
      entities: [Customer],
    }),
    TypeOrmModule.forRoot({
      ...
      name: 'SubDBConnection',
      host: 'localhost',
      entities: [User],
    }),
  ],
})
...

여기서 중요한것은 여러개 연결중에 반드시 1개의 default 설정이 있어야 한다.
(혹은 name을 비워두면 default가 된다)

Default Connection을 사용한 DB 연결

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Customer } from './entity';
import { CustomerController } from './controller/customer.controller';
import { CustomerService } from './service/customer.service';

@Module({
  imports: [
    TypeOrmModule.forFeature([Customer]),
  ],
  controllers: [CustomerController],
  providers: [CustomerService],
})
export class CustomerModule {}

default 설정을 사용한 연결이라면 Module에 특별히 설정해줄게 없다. 아무 설정 하지않으면 default 연결을 사용한다.

SubDBConnection 로 연결

default가 아닌 특정 이름의 DB 에 연결하기 위해서는 Module의 엔티티 설정 부분에 connection의 name 을 명시해준다.

import { Global, Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CustomerLogController } from './controller/customer-log.controller';
import { CustomerLog } from './customer-log.entity';
import { CustomerLogService } from './service/customer-log.service';

@Module({
  imports: [TypeOrmModule.forFeature([CustomerLog], 'SubDBConnection')],
  providers: [AccessLogService, ConfigService],
  controllers: [CustomerLogController],
  exports: [CustomerLogService],
})
export class CustomerLogModule {}

여기서 바뀐점은 imports: [TypeOrmModule.forFeature([CustomerLog], 'SubDBConnection')], 이 부분이다. entity 와 함께 어떤 connection을 사용할지 name을 지정해준다.

import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { BaseCrudOperations } from '@common/common-support';
import { CustomerLogEntity } from '@core/entity';

@Injectable()
export class CustomerLogRepository extends BaseCrudOperations<CustomerLogEntity> {
   constructor(
           @InjectRepository(CustomerLogEntity, 'SubDBConnection')
           private readonly customerLogRepository: Repository<CustomerLogEntity>,
   ) {
      super(customerLogRepository);
   }
}

마지막으로 Repository 주입받는 코드에 @InjectRepository(CustomerLogEntity, 'SubDBConnection') 이와같이 connection 이름을 지정해준다.

이 기록이 도움이 되었길 바란다.