몇일전 nestjs 에서 레포지토리쪽 코드를 작성하는데 쿼리빌더에서 select를 해오지 못하는 현상이 발생하였다. 분명히 기존 다른 코드들은 getMany()로 select를 해서 그대로 사용했을 뿐인데 오류메세지가 'cant find databaseName' 이 발생하였다.
나는 어리둥절하면서 구글링을 열심히 해봤는데 db 커넥션을 조정해보라는 글밖에 찾지 못하다가 해결방법을 찾아냈다.
그거슨 바로 getRawMany()로 바꾸는 것이었다.
근데 대체 getRawMany()랑 getMany()가 뭔차이길래?!! 왜 데이터베이스 이름을 찾을수 없다고 뜨는걸까?
차이점이 그래서 뭔데??
- queryBuilder.getRawMany() 랑 queryBuilder.getMany() 의 주요 차이점은 반환되는 데이터 형태에 있다.
1. queryBuilder.getRawMany()
해당 메소드는 쿼리 결과를 원시 데이터 형태로 반환한다. 이 뜻은 DB에서 직접 반환된 형식 그대로의 데이터를 받게되는 것이다. 그래서 sql 쿼리 결과를 그대로 얻고 싶을때 사용되며, select 문에서 지정한 컬럼 이름을 그대로 키로 사용하는 객체의 배열을 반환하게 된다.
2. queryBuilder.getMany()
해당 메소드는 쿼리 결과를 nestjs/typeORM의 엔티티 인스턴스 형태로 반환한다. 즉 결과 데이터는 해당 엔티티 클래스의 인스턴스로 매핑되어 반환한다. 이 방법은 데이터를 엔티티 객체로 작업할 때 유용하며, 엔티티 클래스에 정의된 프로퍼티에 맞게 데이터가 자동으로 매핑된다.
내가 오류가 난 코드 예시
첫번째는 내가 처음에 getMany()를 썼을 때 에러가 나던 코드이고 두번째는 getRawMany를 사용해서 해결한 코드이다.
<오류가 났던 코드>
async searchVendorUsers(pagingArgs: PagingInput, phone?: string) {
const queryBuilder = await this.vendorUserRepository
.createQueryBuilder('cvu')
.select([
'cvu.vendor_user_id as vendorUserId',
'cvu.vendor_id as vendorId',
'cv.grade as grade',
'cv.vendor_name as vendorNm',
'rn.user_type as userType',
'cvu.user_account as account',
'cvu.user_hp as phone',
'cvu.user_name as name',
'cv.test_yn as operateYn',
'cvu.use_yn as useYn',
])
.leftJoin(VendorEntity, 'cv', 'cv.vendor_id = cvu.vendor_id')
.leftJoin(VendorUserRightNewEntity, 'rn', 'rn.vendor_user_id = cvu.vendor_user_id');
if (phone) {
queryBuilder.where('user_hp = :phone', { phone });
}
const { limit, page } = pagingArgs;
const offset = (page - 1) * limit;
// 페이징 적용
const data = queryBuilder.offset(offset).limit(limit);
const vendorUsers = await data.getMany();
const count = await data.getCount();
return { vendorUsers, count };
}
<해결된 코드>
async searchVendorUsers(pagingArgs: PagingInput, phone?: string) {
const queryBuilder = await this.vendorUserRepository
.createQueryBuilder('cvu')
.select([
'cvu.vendor_user_id as vendorUserId',
'cvu.vendor_id as vendorId',
'cv.grade as grade',
'cv.vendor_name as vendorNm',
'rn.user_type as userType',
'cvu.user_account as account',
'cvu.user_hp as phone',
'cvu.user_name as name',
'cv.test_yn as operateYn',
'cvu.use_yn as useYn',
])
.leftJoin(VendorEntity, 'cv', 'cv.vendor_id = cvu.vendor_id')
.leftJoin(VendorUserRightNewEntity, 'rn', 'rn.vendor_user_id = cvu.vendor_user_id');
if (phone) {
queryBuilder.where('user_hp = :phone', { phone });
}
const { limit, page } = pagingArgs;
const offset = (page - 1) * limit;
// 페이징 적용
const data = queryBuilder.offset(offset).limit(limit);
const vendorUsers = await data.getRawMany();
const count = await data.getCount();
return { vendorUsers, count };
}
사실 getMnay()를 getRawMany() 로만 바꿨을 뿐인데 해결되었다.
아마 해결된 이유는 내가 select에서 여러 컬럼들을 지정했는데 해당 컬럼들이 내가 만든 엔티티에 제대로 매핑되지 않아서 getMany로는 안되던 것 같다.
왜냐면 아래의 코드에서는 select를 사용하지 않는데, 이는 엔티티 그대로를 가져오기 때문에 getMany()가 되었던 것이고, 내가 select에서 지정한다면 엔티티와 만약 맞지 않는다면 cant find databaseName 에러가 발생하는 듯 하다.
<getMany()가 잘 적용되는 코드예시>
async findGroupMasterUser(bizGroupNo: string[]) {
const query = this.sysUserRepository
.createQueryBuilder('sysUser')
.innerJoin('USER_BIZ_AUTH', 'userBizAuth', 'sysUser.USER_NO = userBizAuth.USER_NO ')
.where(`userBizAuth.BIZ_GROUP_NO in (${bizGroupNo})`)
.andWhere(`sysUser.GROUP_ADMIN_YN = 'Y'`)
.andWhere(`sysUser.ROW_STS_CD = 'U'`);
return query.getMany();
}
'백엔드 > NestJs' 카테고리의 다른 글
nestjs) 미들웨어,가드,필터 (0) | 2025.03.13 |
---|---|
[nestjs] PickType,OmitType, PartialType (0) | 2023.09.25 |
리졸브필드(resolveField) (0) | 2023.07.31 |
권한설정 (0) | 2023.07.18 |
[nestjs] new DataLoader (0) | 2023.07.02 |