TypeScript ORM

ORM이 SQL 경계를 감싸는 방식

엔티티, 리포지토리, 쿼리 빌더, 마이그레이션이 어디까지 SQL을 숨기고 어디서 직접 드러내야 하는지 나눈다.

01

엔티티 선언

테이블과 컬럼을 TypeScript 클래스 또는 스키마로 표현해 도메인 모델과 연결한다.

metadata
02

리포지토리 호출

단순 CRUD는 repository 메서드로 처리해 반복 SQL을 줄인다.

기본 경로
03

복잡 쿼리

JOIN, aggregate, pagination은 QueryBuilder나 raw SQL로 의도를 노출한다.

예외 경로
04

마이그레이션

스키마 변경은 코드 배포와 분리된 순서로 기록하고 롤백 가능성을 확인한다.

스키마 변경 이력
장점
타입 안전한 접근과 반복 CRUD 제거가 생산성을 만든다. 관계 매핑과 validation을 코드 근처에 둘 수 있다.
developer speed
위험
N+1, 암시적 lazy loading, 과한 추상화가 성능을 숨긴다. 쿼리 로그와 EXPLAIN을 보는 루틴이 필요하다.
hidden SQL
경계
성능 핵심 경로는 ORM 편의보다 실제 SQL 형태를 우선한다. 인덱스와 lock 동작은 ORM 문법만으로 판단하지 않는다.
database truth

ORM 사용 전 확인

쿼리 로그 개발 환경에서 실제 SQL과 실행 횟수를 바로 볼 수 있다.
트랜잭션 여러 write가 하나의 비즈니스 작업이면 transaction boundary를 명시한다.
마이그레이션 자동 동기화는 운영에서 끄고 migration 파일로 추적한다.

쿼리 경계 예시

repo.find({ relations: { author: true } })
// 느려지면 QueryBuilder + EXPLAIN으로 실제 JOIN을 확인