(TypeORM) TypeORM - Entity

최건·2025년 5월 8일

참고 문서

Entity란?

  • Entity는 데이터베이스 테이블에 매핑되는 클래스이다.
  • 즉, TypeORM에서는 User와 같은 클래스를 만들고 여기에 데코레이터(@Entity, @Column 등)를 붙여주면, 그것이 곧 데이터베이스의 하나의 테이블이 된다.
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";

@Entity()  // 이 클래스는 테이블로 매핑된다
export class User {
  @PrimaryGeneratedColumn()  // 기본키 + AUTO_INCREMENT
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column()
  isActive: boolean;
}

@Column() 이란?

@Column()
firstName: string;
  • @Column() 데코레이터를 사용하면 이 속성이 데이터베이스 테이블의 열로 매핑된다.

  • 데이터 타입은 TypeScript의 타입을 기준으로 자동 추론된다 (예: string → varchar, number → int).

  • 자세한 내용은 뒤에 있다.

@Primary Column()이란?

  • Entity는 반드시 최소한 하나의 Primary Key를 가져야 한다.
데코레이터설명
@PrimaryColumn()수동 지정 필요. 직접 값을 넣어야 함
@PrimaryGeneratedColumn()자동 증가(AUTO_INCREMENT) 숫자 ID
@PrimaryGeneratedColumn("uuid")자동 생성 UUID 문자열 ID

복합 기본 키 사용 법

@Entity()
export class User {
  @PrimaryColumn()
  firstName: string;

  @PrimaryColumn()
  lastName: string;
}
  • 두 컬럼을 함께 기본 키로 사용한다.
  • 데이터는 firstName + lastName 조합이 고유해야 저장된다.

TypeORM Special Columns

데코레이터용도 설명자동 설정 시점컬럼 타입사용 예시
@CreateDateColumn()레코드가 처음 생성된 시간을 자동 저장INSERT 시 자동 설정Date생성일 저장 (createdAt)
@UpdateDateColumn()레코드가 수정된 시간을 자동 저장INSERT, UPDATE 시 갱신Date수정일 저장 (updatedAt)
@DeleteDateColumn()소프트 삭제(soft-delete) 된 시간 저장softRemove() 호출 시 설정Date삭제일 저장 (deletedAt)
@VersionColumn()레코드의 **버전(숫자)**을 저장하며, 저장 시마다 자동 증가save() 호출 시 증가number낙관적 락 버전 관리용 (version)

예시 코드:

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

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

  @Column()
  name: string;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @DeleteDateColumn()
  deletedAt?: Date;  // soft-delete되기 전에는 null

  @VersionColumn()
  version: number;
}

생성되는 DB 테이블 예시

컬럼 이름타입설명
idint기본 키 (자동 증가)
namevarchar유저 이름
createdAtdatetime생성 시간 (자동 설정됨)
updatedAtdatetime수정 시간 (자동 갱신됨)
deletedAtdatetime (null)소프트 삭제 시간 (삭제 시 설정)
versionint버전 번호 (매 저장 시 증가)

컬럼 타입 지정 방법

1. 기본 문법

@Column("int")
age: number;

2. 옵션 객체로 지정

@Column({ type: "int", width: 11 })
age: number;

3. 문자열 길이 지정 (varchar 등)

@Column("varchar", { length: 200 })
name: string;

MySQL / MariaDB에서 지원하는 주요 컬럼 타입

타입설명TypeScript 타입
int, integer일반 정수number
tinyint아주 작은 정수 (0~255)number, boolean
bigint아주 큰 정수 (JS에서는 string)string
float, double실수number
decimal고정 소수점 숫자 (금융용)string
boolean, bool불리언 값boolean
date날짜Date
datetime날짜 + 시간Date
timestamp타임스탬프Date
char, varchar고정 / 가변 길이 문자열string
text 계열긴 텍스트 (tinytext ~ longtext)string
blob 계열바이너리 데이터Buffer
enum, set제한된 값 중 선택string
jsonJSON 객체object
uuidUUID 문자열 (MariaDB 한정)string
point, geometry공간 데이터string (WKT 형식)

bigint 주의사항

  • bigint는 JavaScript의 number 범위를 초과하므로 TypeORM에서는 string으로 매핑된다.
@Column("bigint")
longValue: string;
const entity = new MyEntity();
entity.longValue = "9007199254740992"; // 문자열로 처리

Enum 컬럼 타입

(추천)

export enum UserRole {
  ADMIN = "admin",
  EDITOR = "editor",
  GHOST = "ghost",
}

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

  @Column({
    type: "enum",
    enum: UserRole,
    default: UserRole.GHOST,
  })
  role: UserRole;
}

또는

 export type UserRoleType = "admin" | "editor" | "ghost";

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

  @Column({
    type: "enum",
    enum: ["admin", "editor", "ghost"],
    default: "ghost",
  })
  role: UserRoleType;
}

set 컬럼 타입

(추천)

export enum UserRole {
  ADMIN = "admin",
  EDITOR = "editor",
  GHOST = "ghost",
}

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

  @Column({
    type: "set",
    enum: UserRole,
    default: [UserRole.GHOST, UserRole.EDITOR],
  })
  roles: UserRole[];
}

또는

export type UserRoleType = "admin" | "editor" | "ghost";

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

  @Column({
    type: "set",
    enum: ["admin", "editor", "ghost"],
    default: ["ghost", "editor"],
  })
  roles: UserRoleType[];
}

simple-array 컬럼 타입

  • string[], number[] 등 배열을 문자열로 콤마(,) 구분해 저장.
@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column("simple-array")
  names: string[];
}
user.names = ["Alex", "Sasha"];
// DB에는 "Alex,Sasha"로 저장됨

simple-json 컬럼 타입

  • JSON 객체를 문자열 형태로 저장 (별도의 JSON 타입 없이도 가능)
@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column("simple-json")
  profile: { name: string; nickname: string };
}
user.profile = { name: "John", nickname: "Malkovich" };
// DB에는 '{"name":"John","nickname":"Malkovich"}'로 저장됨

한계

한계설명
❌ 쿼리 불가SQL에서는 객체 내부 필드를 조건으로 검색 불가 (WHERE profile.name = 'John' 불가능)
❌ 인덱싱 불가내부 필드에 인덱스를 걸 수 없음
❌ 데이터 무결성 없음구조 강제 불가 (profile.name이 string인지 보장 불가)
❌ 정렬, 조인 불가JSON 안의 값으로 정렬하거나 조인할 수 없음
❌ 대용량 시 성능 저하큰 JSON이 많아지면 성능 및 관리 복잡도 증가

@Generated() 데코레이터란?

  • TypeORM에서 데이터베이스가 자동으로 생성해주는 값을 가지는 컬럼에 붙이는 데코레이터

지원되는 생성 타입

생성 타입설명지원 DB
"uuid"UUID 자동 생성 (문자열)대부분 (MySQL, Postgres 등)
"increment"숫자 자동 증가 (auto-increment)MySQL, SQLite 등
"identity"Postgres 10+의 GENERATED BY DEFAULT AS IDENTITYPostgreSQL 10 이상
"rowid"CockroachDB의 내부 row 식별자CockroachDB

UUID 자동 생성 컬럼

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

  @Column()
  @Generated("uuid")
  uuid: string;
}

숫자 자동 증가 컬럼 (비기본키)

@Entity()
export class Order {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  @Generated("increment")
  orderNumber: number;
}

Column 옵션

옵션 이름설명사용 예시 / 적용 대상비고
type컬럼의 데이터베이스 타입 지정"varchar", "int", "decimal"필수
nameDB에서의 컬럼명 (기본: 변수명과 동일)name: "user_name"
length문자열 컬럼 길이 지정 (varchar(150) 등)length: 150문자형 컬럼에서만 적용
width숫자 타입의 표현 너비 설정 (MySQL만)width: 5시각적 효과용, MySQL만 지원
onUpdateON UPDATE 트리거 (MySQL 전용)onUpdate: "CURRENT_TIMESTAMP"timestamp 등에서 사용
nullableNULL 허용 여부 (true이면 NULL 허용)nullable: true기본값: false
updatesave() 시 해당 컬럼이 업데이트 될지 여부update: falseinsert만 허용하고 싶을 때
insertsave() 시 insert 여부 제어insert: falseupdate만 허용하고 싶을 때
selectfind() 등 조회 시 포함 여부 설정select: false기본: true, 숨기고 싶을 때
defaultDB 레벨에서 기본값 설정default: "guest"
primaryPrimary Key 여부 설정primary: true@PrimaryColumn과 동일 역할
uniqueUNIQUE 제약 조건 부여unique: true
commentDB에 컬럼 설명 추가comment: "사용자 이름"일부 DB에서만 지원
precisiondecimal 타입의 전체 자릿수 설정precision: 10정밀 소수용 (12345.6789)
scaledecimal 타입의 소수점 이하 자릿수 설정scale: 2위와 함께 사용해야 함
zerofill숫자 타입 앞에 0 채움 (MySQL 전용)zerofill: true자동 UNSIGNED 처리됨
unsigned음수를 허용하지 않음 (MySQL 전용)unsigned: true정수형에서만 유효
charset문자 집합 설정charset: "utf8mb4"문자형 컬럼에만 적용
collation정렬 방식 설정collation: "utf8mb4_general_ci"문자형 컬럼에만 적용
enum열거형 값 배열 또는 enum 클래스 설정enum: UserRole or enum: ["admin", ...]enum 또는 set 타입에서 사용
enumNamePostgreSQL에서 enum 타입 이름 지정enumName: "user_role_enum"PostgreSQL 전용
asExpression계산된 컬럼 정의 (Generated Column 표현식)asExpression: "price * quantity"MySQL 전용 (VIRTUAL, STORED)
generatedTypeGenerated Column의 저장 방식 지정 (VIRTUAL or STORED)generatedType: "VIRTUAL"MySQL 전용
hstoreTypePostgreSQL의 HSTORE 컬럼 처리 방식 지정 (object or string)hstoreType: "object"PostgreSQL 전용
array배열 컬럼 여부 (예: int[])array: truePostgreSQL, CockroachDB
transformer커스텀 변환기 (DB <-> App 타입 매핑)transformer: { from: ..., to: ... }암호화, 포맷 처리 등에 유용
profile
개발이 즐거운 백엔드 개발자

0개의 댓글