1. Type ORM이란?
✅ TypeScript와 JavaScript를 위한 ORM(Object Relational Mapping) 라이브러리로, 객체 모델을 데이터베이스의 관계형 테이블로 매핑해주는 도구이다. 이를 통해 SQL 쿼리를 작성하지 않고도 객체 지향 방식으로 데이터베이스를 다룰 수 있다.
주요 특징 or 기능
- 데이터베이스 독립성 : 다양한 데이터베이스를 지원한다. (예 : mongoDB, PostgreSQL, MySQL 등)
- 관계 설정 및 관리 : One-to-Many, Many-to-Many 등 관계형 데이터베이스의 관계를 쉽게 설정 가능
- 마이그레이션 및 쿼리빌더 기능 제공
- 모듈화된 구조 덕분에 TypeORM이 NestJS의 DI(Dependency Injection) 시스템과 쉽게 통합할 수 있다.
이 외에도 다양한 기능을 지원한다.
사용 방법
npm install @nestjs/typeorm typeorm
명령어로 typeorm
을 설치하고 모듈을 등록한다.
@Module({
imports: [
// forRoot는 모듈을 등록할 때 쓰고 , 연결하고 싶은DB의 정보를 넣어주면됨
TypeOrmModule.forRoot({
type: process.env.DB_TYPE as 'postgres',
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT),
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATEBASE,
entities: [],
synchronize: true, // 배포환경에서는 무조건 false , DB가 싱크를 맞추다가 날아갈 수 가 있음 추후에 마이그레이션으로 관리함
}),
MovieModule,
],
})
export class AppModule {}
AppModule
에 TypeOrmModule.forRoot
로 모듈을 등록하고, 연결하고 싶은 DB의 정보를 속성에 맞게 넣어준다.
Entity 생성
import { Exclude, Expose, Transform } from 'class-transformer';
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
UpdateDateColumn,
VersionColumn,
} from 'typeorm';
// @Exclude() // 클래스 전체를 Exclude해서 아무것도 안보이게 할 수 있음
@Entity()
export class Movie {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
genre: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
@VersionColumn()
version: number;
}
@Entity
로 클래스를 테이블이라는 것을 명시한다.
@Column
으로 테이블의 칼럼을 생성한다.
id
의 @PrimaryGeneratedColumn
은 자동으로 생성되는 id
칼럼을 설정해준다.
@CreateDateColum
은 자동으로 생성시 날짜와 시간을 저장한다.
@UpdateDateColumn
은 자동으로 업데이트 된 날짜와 시간을 저장한다.
@VersionColumn
은 자동으로 업데이트 될 때마다 1씩 증가한다.
Column 옵션
옵션 이름 | 타입 | 기본값 | 설명 |
---|
type | string | 자동 감지 | 데이터 타입 (e.g., varchar , int , boolean , date ) |
name | string | 컬럼 이름과 동일 | 컬럼의 커스텀 이름을 지정 |
nullable | boolean | false | 컬럼이 NULL 값을 허용할지 여부 |
unique | boolean | false | 컬럼에 고유 제약 조건 추가 |
default | any | 없음 | 컬럼의 기본값 (정적 값 또는 함수) |
comment | string | 없음 | 컬럼에 주석 추가 |
primary | boolean | false | 해당 컬럼을 기본 키로 설정 |
generated | string | 없음 | 자동 생성 옵션 (increment , uuid , rowid 등) |
select | boolean | true | 기본 쿼리에서 해당 컬럼을 포함할지 여부 |
이 외에도 다양한 옵션들이 있다.
Relationships(관계 설정)
@OneToOne
: A 테이블의 Row 하나와 B 테이블의 Row 하나가 연결되는 관계
@ManyToOne
: A 테이블의 Row 여러개와 B 테이블의 Row 하나가 연결되는 관계
@OneToMany
: A 테이블의 Row 하나와 B 테이블의 Row 여러개가 연결되는 관계
@ManyToMany
: A 테이블의 Row 여러개와 B 테이블의 Row 여러개가 연결되는 관계
@OneToOne 관계
// user.entity.ts
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToOne(() => Profile, (profile) => profile.user, { cascade: true })
@JoinColumn()
profile: Profile;
}
// profile.entity.ts
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number;
@Column()
bio: string;
@OneToOne(() => User, (user) => user.profile)
user: User;
}
User
와 Profile
엔티티에 1:1
관계를 설정했다.
JoinColumn
을 사용해서 외래 키 컬럼을 명시적으로 지정한다.
cascade: true
로 부모의 엔티티가 저장되면 자식 엔티티도 자동으로 저장된다.
@OneToMany & @ManyToOne 관계
// user.entity.ts
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => Post, (post) => post.user)
posts: Post[];
}
// post.entity.ts
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@ManyToOne(() => User, (user) => user.posts, { onDelete: 'CASCADE' })
user: User;
}
@OneToMany
로 1:N
관계를 설정한다. 배열([])
타입으로 정의한다.
@ManyToOne
로 N:1
관계를 설정한다.
onDelete: 'CASCADE'
로 부모 엔티티 삭제 시 자식 엔티티도 자동으로 삭제된다.
@ManyToMany 관계
// student.entity.ts
@Entity()
export class Student {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => Class, (classEntity) => classEntity.students, { cascade: true })
@JoinTable()
classes: Class[];
}
// class.entity.ts
@Entity()
export class Class {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => Student, (student) => student.classes)
students: Student[];
}
@ManyToMany
로N:N 관계를 설정한다.
@JoinTable
로 두 테이블 사이에 중간 테이블을 생성한다. 반드시 한쪽에만 설정해야한다.
cascade: true
로 관계된 엔티티를 자동으로 저장한다.
참조