TypeORM으로 쿼리 작성

쿼리빌더 생성

TypeORM 쿼리

TypeORM에는 create, save, find, findOne, createQueryBuilder 등 있다. 복잡한 우리의 알고리즘을 위해 createQueryBuilder를 사용하자.

쿼리 설치하기

컨트롤러로 간다.

1
2
3
4
5
// reports.controller.ts
@Get()
 getEstimate(@Query() query: GetEstimateDto) {
  return this.reportsService.createEstimate(query);
 }

서비스에 메서드를 추가하자

1
2
3
4
5
6
// reports.service.ts
import { GetEstimateDto } from './dtos/get-estimate.dto';

createEstimate(estimateDto: GetEstimateDto) {
    return this.repo.createQueryBuilder().select('*').getRawMany();
  }

우선은 모든 속성을 받도록 쿼리를 작성했다. 서버를 실행하고 API Client에서 만들어 놓은 추정치를 받는 요청을 보내보자. 속성들이 잘 오면 성공.

쿼리 작성하기

같은 제조사 찾기

1
2
3
4
5
6
7
8
// reports.service.ts
createEstimate(estimateDto: GetEstimateDto) {
    return this.repo
    .createQueryBuilder()
    .select('*')
    .where('make = :make', { make: estimateDto.make })
    .getRawMany();
  }

위와 같이 작성 후 다시 API Client를 테스트햅면 같은 제조사 레코드만 나타난다.

.where('make = :make', { make: estimateDto.make }) 이 코드는 make를 기준으로 받은 make값과 같은 값을 가진 속성들을 찾는다. 우린 toyota로 요청했으니 toyota만 나왔던 것이다.

위 코드를 조금 줄이고자, estimateDto 로 make를 지정하지 않고 바로 make를 지정해보자

1
2
3
4
5
6
7
8
// reports.service.ts
createEstimate({make}: GetEstimateDto) {
    return this.repo
    .createQueryBuilder()
    .select('*')
    .where('make = :make', { make })
    .getRawMany();
  }

이처럼 다른 속성들도 연속해서 추가한다. 다만 조건은 중첩되니까 where이 아니라 andwhere를 쓴다. 3개를 반환하고 평균 가격을 찾는 쿼리까지 작성하고, 관리자가 승인한 보고서만 추출하면 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// reports.service.ts
createEstimate({ make, model, lng, lat, year, mileage }: GetEstimateDto) {
    return this.repo
      .createQueryBuilder()
      .select('AVG(price)', 'price')
      .where('make = :make', { make })
      .andWhere('model = :model', { model })
      .andWhere('lng - :lng BETWEEN -5 AND 5', { lng })
      .andWhere('lat - : lat BETWEEN -5 AND 5', { lat })
      .andWhere('year - :year BETWEEN -3 AND 3', { year })
      .andWhere('approved IS TRUE')
      .orderBy('mABS(ileage - :mileage)', 'DESC')
      .setParameters({ mileage })
      .limit(3)
      .getRawOne();
  }

테스트

  • 다양한 속성으로 설정하여 레코드를 추가하여 테스트해보자