DevBoi

[NestJs] TypeOrm 0.2 -> 0.3 버전 변경 본문

Develop/[NestJs]

[NestJs] TypeOrm 0.2 -> 0.3 버전 변경

HiSmith 2023. 8. 20. 19:29
반응형

0.2버전은 레퍼런스도 많고, 좀더 자료가 많아서 진행했는데

다른 라이브러리 때문에 자꾸 충돌이 난다.

그래서 대규모 버전 변경 작업을 한다.

 

작업 내용은 deprecate된 부분을 변경하면서 수정하고, 설계에 대한 수정사항을 수정한다.

 

1. @EntityRepository deprecated   0.3 버전에서는 사용할 수 없다.

왜 typeorm의 버전을 올리면서 스택자체를 날려버린건지 이해는 안되지만 무튼..

 

CustomRepository Decorator + CustomRepository Module이 필요하다.

import { SetMetadata } from "@nestjs/common";

export const TYPEORM_EX_CUSTOM_REPOSITORY = "TYPEORM_EX_CUSTOM_REPOSITORY";

export function CustomRepository(entity: Function): ClassDecorator {
  return SetMetadata(TYPEORM_EX_CUSTOM_REPOSITORY, entity);
}
import { DynamicModule, Provider } from "@nestjs/common";
import { getDataSourceToken } from "@nestjs/typeorm";
import { DataSource } from "typeorm";
import { TYPEORM_EX_CUSTOM_REPOSITORY } from "./typeorm-decorator";

export class TypeOrmCustomModule {
  public static forCustomRepository<T extends new (...args: any[]) => any>(repositories: T[]): DynamicModule {
    const providers: Provider[] = [];

    for (const repository of repositories) {
      const entity = Reflect.getMetadata(TYPEORM_EX_CUSTOM_REPOSITORY, repository);

      if (!entity) {
        continue;
      }

      providers.push({
        inject: [getDataSourceToken()],
        provide: repository,
        useFactory: (dataSource: DataSource): typeof repository => {
          const baseRepository = dataSource.getRepository<any>(entity);
          return new repository(baseRepository.target, baseRepository.manager, baseRepository.queryRunner);
        },
      });
    }

    return {
      exports: providers,
      module: TypeOrmCustomModule,
      providers,
    };
  }
}

 

해당 데코레이터 및 모듈을 사용하는 기존 소스는 아래와 같이 바뀐다.

@Injectable()
export class CorpService {
  constructor(
    private  corpRepository : CorpRepostiory
  ){}
@Module({
    imports: [TypeOrmCustomModule.forCustomRepository([CorpRepostiory])],
    controllers: [CorpController],
    providers: [CorpService,CorpRepostiory],
})
export class CorpModule {}
@CustomRepository(Corp)
export class CorpRepostiory extends Repository<Corp>{

 

 

2. 굳이 데코레이션 만들어서 우회하지 않고, typeorm의 0.3 방식을 그대로 흡수하기

 

변경된 Repository

생성자 부분에서 datasource로 엔티티 매니저를 생성하고 이를 파라미터로 넘겨준다.


@Injectable()
export class CorpRepostiory extends Repository<Corp>{
    constructor(private dataSource: DataSource) {
        super(Corp, dataSource.createEntityManager());
      }

    
    async findbyCorpId(id: number): Promise<Corp>{
    const corp = 
    await this
                .createQueryBuilder("corp")
                .where("corp.id = :id",{id}) 
                .getOne();
    return corp;
    }
    
}

해당 과 같이 하면 , service layor에서 사용하던 기본 typeorm에 대한 펑션은 바꿔줘야 한다.

 

<typeorm 0.2>
 const corp = await this.corpRepository.findOne(corpId);
 
<typeorm 0.3>
 const corp = await this.corpRepository.findOneBy({
      id: corpId // where id is your column name
  });
<typeorm 0.3>(나는 이걸로 씀)
const result =  this.memberRepository.findOne(
      {
        where:{id : id}
      }
    );

 

typeorm 0.3버전은 조건절에 nest방식을 지원해준다.

사실 where 구문에 대한 프로그래밍이 답이좀 없긴했었는데 이 부분이 개선 된 것같다.

 

무튼 해당 방식으로 하면 , typeorm에 대한 버전을 업그레이드 하고 이슈가 없다.

 

나는 개인적으로 커스텀 데코레이터를 사용하는건...별로 좋아보이지 않는다

왜냐면, 결국 우회이기 때문에 typeorm 버전에 따라 다시 수정해야할 수도 있어 보인다.

반응형