2022년 3월 TypeORM이 0.3 버전으로 새롭게 배포되면서 많은 것이 달라진 듯하다. 이전에 봤던 함수들이 deprecated 되었고 DB 설정 방식이나 repository 이용 방법 등이 달라졌다. 오랜만에 TypeORM을 사용하면서 기존과 많이 달라졌고 구글링 해도 예전 방식의 설명이 많아 혼란스러웠기에 어떤 점이 바뀌었는지 간단하게 적어보려고 한다.
@EntityRepository
EntityRepository
는 repository 패턴
을 이용해 Active Recorder에 없는 함수를 정의할 때 사용하던 Decorator이다.
@EntityRepository()
class UserRepository extends Repository<User> {}
기존에는 위와 같이 사용되었지만 deprecated 되면서 이용할 수 없게 되었다.
나는 급한 데로 아래와 같이 custom Decorator
를 정의하는 방법으로 이용했다.
// typeorm-ex.decorator.ts
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);
}
이렇게 decorator를 만들어준 후 Dynamic module
을 정의해줬다.
// typeorm-ex.module.ts
import { DynamicModule, Provider } from '@nestjs/common';
import { getDataSourceToken } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';
import { TYPEORM_EX_CUSTOM_REPOSITORY } from '../decorators/';
/* CUstomRepository decorator가 적용된 repository를 받아줄 module */
export class TypeOrmExModule {
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: TypeOrmExModule,
providers,
};
}
}
참고
https://velog.io/@pk3669/typeorm-0.3.x-EntityRepository-%EB%8F%8C%EB%A0%A4%EC%A4%98
하지만 위의 경우는 기존 TypeORM 0.2.x 버전에서 EntityRepository Decorator가 동작을 안 할 때의 해결하는 방법이다.
만약 새롭게 프로젝트를 시작한다면 @Injectable()
을 사용해 repository 패턴을 이용한 코드 작성이 가능하다.
Injectable을 사용하려면 아래와 같이 작성해 기존의 내용과 같게 코드 작성이 가능하다.
@Injectable()
export class UserRepository {
constructor(
@InjectRepository(User)
private readonly user: Repository<User>,
) {}
}
자세한 사용법은 공식문서에서 확인 -> https://docs.nestjs.com/recipes/sql-typeorm#getting-started
find - select
find()
함수에서 select의 사용 방식이 바뀌었다.
userRepository.find({
select: ["id", "firstName", "lastName"]
})
===>
userRepository.find({
select: {
id: true,
firstName: true,
lastName: true,
}
})
where
find()
함수 내에서 where
을 사용할 때 아래와 같이 관계 옵션을 계층적으로 사용이 가능하다.
userRepository.find({
where: {
photos: {
album: {
name: "profile"
}
}
}
})
method 추가
findOneBy
, findOneByOrFail
, findBy, countBy
, findAndCountBy
가 추가되었다고 한다.
const users = await userRepository.findBy({
name: "Michael"
})
이들 외에도 connection에서의 DataSource
라는 것과 Transaction
의 방식 등 많은 것이 바뀌었다. 생가하기에는 안 바뀐 것 빼고 다 바뀐 것 같다,,, 아마 change log를 보면서 자세히 공부해봐야겠다...
TypeORM ChangeLog - https://github.com/typeorm/typeorm/blob/master/CHANGELOG.md
'Backend > DataBase' 카테고리의 다른 글
[MySQL] 자연어 검색 (FULLTEXT) (2) | 2024.12.15 |
---|---|
[DB] RDB와 NoSQL의 수평확장 (Scale Out) (0) | 2022.08.07 |
[MongoDB] MongoDB Atlas Trigger (Scheduled Trigger) (0) | 2022.07.10 |