개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

NestJS Entity — 데이터베이스 테이블과 매핑되는 클래스

2025년 3월 6일
NestJSEntityTypeORMPrismaORM

애플리케이션이 데이터베이스와 대화하려면 테이블 구조를 코드로 표현해야 한다. NestJS에서는 Entity 클래스가 그 역할을 맡으며, ORM이 이 클래스를 읽어 SQL 스키마를 생성하거나 쿼리를 자동으로 만들어낸다. TypeORM과 Prisma 두 가지 방식이 널리 쓰이며, 선택에 따라 Entity를 정의하는 방법이 달라진다.

TypeORM Entity

TypeORM은 데코레이터를 붙인 클래스 자체가 Entity가 된다.

import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn } from 'typeorm';

@Entity('users')
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 100 })
  name: string;

  @Column({ unique: true })
  email: string;

  @Column({ default: true })
  isActive: boolean;

  @CreateDateColumn()
  createdAt: Date;
}

@Entity — 이 클래스가 데이터베이스 테이블에 매핑됨을 선언. 인자로 테이블 이름을 지정할 수 있다.

@PrimaryGeneratedColumn — AUTO_INCREMENT 기본 키 컬럼. uuid 옵션을 주면 UUID를 생성한다.

@Column — 일반 컬럼. type, length, nullable, unique, default 등의 옵션을 지원한다.

Prisma Model

Prisma는 별도의 스키마 파일(schema.prisma)에 모델을 선언한다.

model User {
  id        Int      @id @default(autoincrement())
  name      String   @db.VarChar(100)
  email     String   @unique
  isActive  Boolean  @default(true)
  createdAt DateTime @default(now())
}

Prisma는 이 스키마를 바탕으로 TypeScript 타입과 클라이언트 메서드를 자동 생성한다. 코드에 데코레이터가 없으므로 Entity 클래스 자체는 존재하지 않고, 생성된 PrismaClient를 통해 데이터에 접근한다.

Entity와 DTO의 차이

Entity와 DTO(Data Transfer Object)는 자주 혼동되지만 역할이 다르다.

구분EntityDTO
목적DB 테이블 매핑계층 간 데이터 전달
위치Repository 레이어Controller ↔ Service
포함 정보컬럼, 관계, 인덱스요청/응답 형식, 유효성 검사
예시UserCreateUserDto, UserResponseDto

Entity에 담긴 민감한 필드(예: password)를 그대로 응답으로 내보내면 보안 문제가 생긴다. DTO를 별도로 만들어 필요한 필드만 노출해야 한다.

데이터 흐름

HTTP Request
     │
     ▼
Controller (DTO로 입력 받음)
     │
     ▼
Service (비즈니스 로직)
     │
     ▼
Repository (Entity로 DB 조작)
     │
     ▼
Database (테이블)

Entity는 Repository 레이어에서만 직접 다루는 것이 원칙이다. Service가 Entity를 Controller에 그대로 반환하면 계층 경계가 무너진다.

관계 매핑

TypeORM은 테이블 간 관계도 데코레이터로 표현한다.

import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';
import { Post } from './post.entity';

@Entity('users')
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @OneToMany(() => Post, (post) => post.author)
  posts: Post[];
}

@OneToMany / @ManyToOne — 1:N 관계를 양방향으로 선언. TypeORM이 JOIN 쿼리를 자동으로 생성한다.

Entity는 데이터베이스 스키마를 코드로 표현하는 단일 진실의 원천(Single Source of Truth)이다. 스키마 변경은 Entity를 수정하고 마이그레이션을 실행하는 것으로 시작된다.

← 이전 글NestJS DTO — 계층 간 데이터를 전달하는 객체
다음 글 →NestJS Middleware — Controller 이전에 실행되는 함수