일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- ethers v6
- 스마트컨트렉트 함수이름 중복 호출
- 러스트기초
- chainlink 설명
- 컨트렉트 동일한 함수이름 호출
- 오블완
- ethers type
- ethers
- 머신러닝기초
- ethers typescript
- 스마트컨트렉트 예약어 함수이름 중복
- 티스토리챌린지
- 체인의정석
- 프록시배포구조
- 스마트컨트렉트테스트
- git rebase
- multicall
- ambiguous function description
- vue기초
- SBT표준
- Vue.js
- nest.js설명
- 컨트렉트 배포 자동화
- 러스트 기초 학습
- 스마트컨트렉트프록시
- rust 기초
- 러스트 기초
- ethers websocket
- Vue
- 스마트 컨트렉트 함수이름 중복
- Today
- Total
체인의정석
TypeORM & NestJS) Query Selector 사용하여 다수의 데이터를 가져오고 Response 구조로 다수의 데이터 응답 보내기 본문
TypeORM & NestJS) Query Selector 사용하여 다수의 데이터를 가져오고 Response 구조로 다수의 데이터 응답 보내기
체인의정석 2021. 11. 3. 15:10다음과 같이 queryBuilder를 사용하면 find() 를 사용할 때보다 더 자유로운 검색이 가능하다.
먼저 getRepository 에는 테이블 이름이 들어가게 되는데 이 테이블은 entites 폴더 안의 dto에 정의를 해둔다.
해당 dto는 데이터베이스와 완전히 똑같은 구조로 정의를 해준다.
이때 계속해서 에러가 나는 부분이 바로 이 entity에 없는 값이라고 에러가 도출되는 부분이였다.
계속해서 해메다가 공식문서를 다시 찾아보게 되었고.
https://typeorm.io/#/select-query-builder/
getOne() => 하나의 값을 도출
getMany() => 여러개의 값을 도출
을 통해 일차적으로 다중 결과값을 처리해 주었다.
또한 여기서 select에 sum 이나 max 같은 연산을 하여 새로운 칼럼을 추가해 주었으므로,
getRawOne() 이다 getRawMany()로 변경해 주어야한다는 사실을 알아서 변경을 해주었다.
그 결과 값이 제대로 도출됨을 확인할 수 있었다.
const transactions = await getRepository(칼럼이름)
.createQueryBuilder()
.select('from_address')
.addSelect('to_address')
.addSelect('COUNT(*)', 'totalTxCount')
.addSelect('SUM(value)', 'sumValue') // 왼쪽은 계산 식 오른쪽은 alias
.addSelect('MAX(block_timestamp)', 'maxTimestamp') //addSelect를 다음과 같이 써서 다중 select 가능
.addSelect('MIN(block_timestamp)', 'minTimestamp')
.where('from_Address = :from_address', {
from_address: from_address, //where 조건절 추가
})
.groupBy('to_address')
.orderBy('value', 'DESC')
.skip(page) //OFFSET : 응답개수 카운트가 시작되는 지점
.take(rpp) //LIMIT : 한번에 응답하는 숫자의 총합
.printSql() // sql 테스트를 위해 프린트 해보기
.getRawMany(); // getMany를 하게 되면 entity와 같은 값만 나옴, rawMany를 해야 위와 같은 연산 처리가 가능하다.
이후에 이러한 값들을 response class로 객체화 시켜서 리턴하여 주기 위하여서 아래와 같이 각각 forEach 문을 돌면서 결과 값을 push해서 리턴해 주었다. 처음에는 map을 써서 push까지 한번에 하려 하였으나. 연산하여 모두 적용하는 것이 아니라 원래 트랜잭션 결과 값을 그대로 받아오는 것이였기 때문에 forEach를 사용하였다.
transactions.forEach((x) => {
const obj: RelatedTransactionsData = {
fromAddress: x.from_address,
toAddress: x.to_address,
totalTxCount: x.totalTxCount,
sumValue: x.sumValue,
maxTimestamp: x.maxTimestamp,
minTimestamp: x.minTimestamp,
};
responseDataArr.push(obj);
});
이렇게 나온 responseDataArr을 response 객체안의 data에 넣어준다.
이렇게 여러개의 data가 나올 때는 해당 data의 총합이 몇개인지 찾아서 구해주는 식도 추가해주는 것이 좋다는 피드백을 받았다.
따라서 다음과 같이 구성하였다.
export class SearchByValueData {
@IsString()
hash: string;
@IsEthereumAddress()
fromAddress: string;
@IsEthereumAddress()
toAddress: string;
@IsNumber()
value: number;
@IsString()
blockTimeStamp: string;
}
export class SearchByValueDataResponse extends CommonResponseData {
items: SearchByValueData[];
}
export class SearchByValueResponse extends CommonResponse {
@IsNumber()
code: number;
messege?: string;
data?: SearchByValueDataResponse;
}
위와 같은 방식으로 진행하면, 응답에 대한 값을 더 체계적으로 줄 수 있다.
여기서 Common Response와 CommonResponseData의 경우 상위 폴더로 빼서 더 간결하게 코드를 작성하였다.
import { IsNumber } from 'class-validator';
export class CommonResponse {
code: number;
message?: string;
}
export class CommonResponseData {
@IsNumber()
count?: number;
}
다음과 같이 작성하여 여러개에 대한 결과값의 수와 데이터를 각각 리턴해 주는식으로 만들었다.
이렇게 다수의 데이터를 조회하고 리턴하는 구조를 한번 작성해 봤다.
'개발 > backend' 카테고리의 다른 글
typescript) typeORM, query Builder, 날짜 검색 구문 쓰기 (0) | 2021.11.15 |
---|---|
class validator 사용하기, 다중 validation 처리하기 (0) | 2021.11.09 |
SQL) Paging 처리하기, 페이징 API 만들기 (0) | 2021.11.02 |
리팩토링) nest.js 기본 구조 체계화 하기 (0) | 2021.10.26 |
TypeORM - query builder/ find 함수로 쿼리기능 구현 (0) | 2021.10.25 |