-
NestJS 마스터 시리즈 13화. TypeORM과 데이터베이스 연동 전략기술과 산업/언어 및 프레임워크 2025. 5. 12. 19:35728x90
"백엔드 개발의 시작은 데이터 모델링에서, 완성은 Repository 패턴에서 결정된다"
NestJS에서 TypeORM을 활용해 데이터베이스와 연동하는 방법을 설명합니다. 연결 설정, Entity 정의, Repository 사용법, 커스텀 쿼리 전략까지 실무 중심으로 정리합니다.
ORM이 필요한 이유
Raw SQL만으로 서비스 규모가 커질수록 다음과 같은 문제를 피할 수 없다:
- SQL 문이 코드에 직접 섞여 가독성이 떨어짐
- 스키마 변경 시 코드 반영이 어렵고 오류 발생
- 테스트 코드 작성이 복잡
NestJS + TypeORM은 Entity 기반의 데이터 모델링, Repository 패턴, Migration 관리까지 통합된 개발 경험을 제공한다.
TypeORM 설치 및 기본 설정
npm install @nestjs/typeorm typeorm pg
- pg는 PostgreSQL 드라이버 (MySQL 사용 시 mysql2 설치)
AppModule에서 설정
import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ imports: [ TypeOrmModule.forRoot({ type: 'postgres', host: 'localhost', port: 5432, username: 'postgres', password: 'password', database: 'mydb', autoLoadEntities: true, synchronize: true, }), ], }) export class AppModule {}
- synchronize: true는 개발 환경에서만 권장 (자동으로 테이블 생성)
- 운영 환경에서는 반드시 Migration 사용
Entity 클래스 생성
Entity는 데이터베이스 테이블의 구조를 표현한다.
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column() name: string; @Column({ unique: true }) email: string; @Column() password: string; }
- NestJS에서는 Entity를 DTO처럼도 사용할 수 있다.
- 단, 비즈니스 로직과 Entity를 분리하는 것이 권장된다.
Repository 패턴으로 데이터 접근
서비스에서 Entity에 직접 접근하지 않고 Repository를 통해 접근하는 것이 원칙이다.
import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { User } from './user.entity'; @Injectable() export class UsersService { constructor( @InjectRepository(User) private usersRepository: Repository<User>, ) {} findAll(): Promise<User[]> { return this.usersRepository.find(); } findOne(id: number): Promise<User> { return this.usersRepository.findOneBy({ id }); } create(userData: Partial<User>): Promise<User> { const user = this.usersRepository.create(userData); return this.usersRepository.save(user); } }
- @InjectRepository()로 DI 컨테이너에서 Repository를 주입
- find(), findOneBy(), save() 등 기본 메서드 지원
고급 사용 – QueryBuilder
복잡한 조건의 SQL은 QueryBuilder로 해결할 수 있다.
this.usersRepository.createQueryBuilder('user') .where('user.email = :email', { email: 'test@example.com' }) .getOne();
- 가독성 있는 SQL 작성 가능
- SQL Injection 방지 지원
실무 적용 시 유의사항
전략 내용
autoLoadEntities 사용 true 설정 시 Module에서 Entities 자동 인식 Repository 패턴 일관성 유지 Service 단에서만 Repository를 호출하도록 설계 Connection Pool 관리 extra 옵션을 활용해 성능 최적화 DTO와 Entity 분리 Domain Layer와 Persistence Layer를 명확히 분리하는 것이 이상적
마무리 인사이트
NestJS와 TypeORM의 조합은 단순한 ORM 연동을 넘어서 구조화된 데이터 관리와 테스트 가능한 Repository 아키텍처를 동시에 제공한다.
- Entity = 데이터 구조 정의
- Repository = 데이터 접근 권한 설정
- Service = 비즈니스 로직 담당
"좋은 백엔드는 Entity → Repository → Service로 이어지는 흐름을 자연스럽게 만들어야 한다"
다음 회차 예고
NestJS 마스터 시리즈 14화. CRUD 실습 – 사용자(User) API를 완성해보자
실제 REST API를 기준으로 Controller, Service, Repository를 조합해 실습 예제를 완성합니다.728x90'기술과 산업 > 언어 및 프레임워크' 카테고리의 다른 글
JHipster 시리즈 5화 - React 프론트엔드 커스터마이징 실전 가이드 (0) 2025.05.12 Python 마스터 시리즈 9화 – 예외 처리 구조: try, except, finally의 설계 원칙과 실전 활용 (0) 2025.05.12 FastAPI 시리즈 9화 - Background Tasks: 비동기 작업을 우아하게 처리하는 방법 (0) 2025.05.12 Spring Boot 시리즈 29편 – RestTemplate vs WebClient: 외부 API 통신 전략 비교와 적용 가이드 (0) 2025.05.12 전자정부 표준프레임워크 시리즈 7화 – 프로젝트 생성기 구조 분석: 자동 생성 코드의 진짜 의미와 실무 활용 전략 (0) 2025.05.12