TypeORM은 Node.js 생태계에서 매우 인기가 많은 ORM(Object-Relational Mapping) 라이브러리 중 하나입니다. 많은 메소드를 제공하며 특히 데이터베이스에서 데이터를 조회할 때 자주 사용되는 메소드 중 하나가 바로 getRawOne()
입니다. 이 포스트에서는 이 메소드의 반환값에 대한 흔한 오해와 이를 올바르게 사용하는 방법을 살펴보겠습니다.
getRawOne 메소드란?
TypeORM에서 데이터 조회를 위한 메소드는 크게 두 가지 형태가 있습니다:
- Entity 객체를 반환하는 메소드:
findOne()
,getOne()
- Raw 객체(JSON 형태)를 반환하는 메소드:
getRawOne()
,getRawMany()
이 중 getRawOne()
은 SQL 쿼리로부터 데이터를 가져올 때, Entity 객체가 아닌 Raw 데이터를 반환합니다. 여기서 Raw 데이터란 데이터베이스에서 조회된 그대로의 JSON 형태의 데이터를 의미합니다.
왜 Entity가 아닌 Raw 데이터를 반환하는가?
많은 개발자들이 getRawOne()
을 사용하다가 종종 다음과 같은 에러 메시지를 접하게 됩니다:
TypeError: result.someEntityMethod is not a function
이는 반환된 객체가 Entity가 아니라 단순한 Raw 데이터이 기 때문입니다. Raw 데이터는 Entity 클래스에 정의된 메소드와 같은 부가 기능을 가지지 않고, 순수한 데이터만을 갖고 있는 객체입니다.
특히, 특정 컬럼만 조회하거나 SUM()
, COUNT()
, AVG()
와 같은 집계 함수를 사용하여 복합적인 쿼리를 구성했을 때는 Entity로의 반환이 적합하지 않습니다. 이 때문에 TypeORM은 Raw 데이터 형태로 결과를 반환합니다.
Raw 데이터를 Entity로 변환하는 방법
Raw 데이터를 받아 이를 다시 Entity로 변환하여 사용하고 싶다면, 다음과 같은 방법을 사용할 수 있습니다:
class-transformer의 plainToInstance
사용
가장 많이 사용되는 방법은 class-transformer
라이브러리의 plainToInstance()
함수를 사용하는 것입니다:
import { plainToInstance } from 'class-transformer';
const rawResult = await repository
.createQueryBuilder("user")
.select(["user.id", "user.firstName", "user.lastName"])
.getRawOne();
const userEntity = plainToInstance(User, rawResult);
이 방법을 사용하면 Entity 클래스에 정의된 메소드와 프로퍼티를 모두 사용할 수 있습니다.
직접 Entity 생성자를 통해 변환
조금 더 직접적인 방법으로 Entity 클래스의 생성자를 활용할 수도 있습니다:
const rawResult = await repository
.createQueryBuilder("user")
.select(["user.id", "user.firstName", "user.lastName"])
.getRawOne();
const userEntity = new User(rawResult);
하지만 이 방식은 생성자의 구조와 Raw 데이터의 키가 정확히 일치해야 하며, TypeORM의 일부 내부 로직과 충돌할 수 있으니 주의가 필요합니다.
언제 Raw 데이터를 사용해야 할까?
getRawOne()
은 다음과 같은 경우에 적극적으로 사용하면 좋습니다:
- 복잡한 SQL 쿼리를 수행해야 하는 경우
- 특정 컬럼만 선택적으로 조회할 때
- 집계함수(SUM, COUNT 등)를 사용할 때
- 빠른 성능이 중요한 리포트 또는 분석성 데이터 조회 시
이 경우 불필요한 Entity 객체의 메모리 사용을 줄이고, 성능을 향상시킬 수 있습니다.
결론
TypeORM의 getRawOne()
메소드를 정확히 이해하고 활용하면 데이터 조회 시 더 유연하고 효율적인 프로그래밍이 가능합니다. Entity로의 변환이 필요하다면 class-transformer
를 사용하는 방식을 추천하며, Raw 데이터를 사용하는 상황을 잘 파악하여 효율적으로 메소드를 선택하시기 바랍니다.