
# nestjs 초기세팅
nest new typeorm (typeorm 자리에 원하는 프로젝트 이름을 넣는다)
- npm 을 선택하고
$ cd typeorm (폴더를 이동하여)
$ nest g res photos (리소스 전체(모듈, 컨트롤러, 서비스) 및 CRUD를 생성한다)
$ nest g res users
- REST API / CRUD endpoint 생성 동의(yes 입력)
# typeorm 초기세팅
[typeorm 공식문서 명시]
- npm i --save typeorm
- npm i reflect-metadata --save
- npm i @types/node -D
- npm i mysql2 --save
[nestjs 공식문서 명시]
- npm i --save @nestjs/typeorm
# DB 연결
- TypeOrmModule.forRoot()에 DB 정보를 연결한다.
- AppModule을 export하면서 실행자 생성을 통해 TypeORM DataSource와 EntityManager 객체를 주입 없이 사용 가능하게 설정한다.
//app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
import { PhotosModule } from './photos/photos.module';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'root',
entities: [],
synchronize: true,
}),
UsersModule,
PhotosModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {
constructor(private dataSource: DataSource) {}
}
# 모델 만들기
- DB 의 테이블 역할을 할 모델을 만든다.
export class Photo {
id: number;
name: string;
description: string;
filename: string;
views: number;
isPublished: boolean;
}
# 엔티티 만들기
- @Entity() 데코레이터를 추가하여 모델을 엔티티로 만들고, 이것 해당 app 어디서든 사용할 수 있다.
- 엔티티로 load/insert/update/remove 는 물론 다른 동작들을 실행할 수 있다.
import { Entity } from 'typeorm';
@Entity()
export class Photo {
id: number;
name: string;
description: string;
filename: string;
views: number;
isPublished: boolean;
}
# 컬럼만들기
- @Column() 데코레이터를 추가하여 테이블에 있는 컬럼으로 명시한다.
import { Column, Entity } from 'typeorm';
@Entity()
export class Photo {
@Column()
id: number;
@Column()
name: string;
@Column()
description: string;
@Column()
filename: string;
@Column()
views: number;
@Column()
isPublished: boolean;
}
# Primary Key(Column) 설정
- 엔티티는 반드시 최소 1개 이상의 primary key를 가져야 한다.
- @PrimaryColumn() 데코레이터를 사용하고, id와 같은 auto-increment 옵션을 주고 싶다면, @PrimaryGeneratedColumn()데코레이터를 사용한다.
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Photo {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
description: string;
@Column()
filename: string;
@Column()
views: number;
@Column()
isPublished: boolean;
}
# 컬럼 타입 설정
- string은 기본적으로 varchar(255)로 설정된다.
- 길이 추가 컬럼 데코레이터 안에 명시한다. {length:100}
- text, double 등 구체적인 타입을 따옴표로 명시한다.
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Photo {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 100 })
name: string;
@Column('text')
description: string;
@Column()
filename: string;
@Column('double')
views: number;
@Column()
isPublished: boolean;
}
# DB 시작하기
- 작성한 엔티티를 <DB 연결> 에서 TypeOrmModule.forRoot({}) 내부 속성 중, entities: [Photo] 처럼 기재한다.
#테이블 생성하기
- npm run start(:dev) 를 통해 서버를 실행해주면 DB에 테이블이 생성된다.
- table-plus와 같은 프로그램을 사용한다면 새로고침을 누르면 확인 가능하고, 터미널에서 mysql을 사용한다면 설정한 database에 들어가서 desc photo를 입력하면 테이블 구조를 확인할 수 있다.
- MySQL 에는 boolean 타입이 없고, 0과 1의 표현을 위해 tinyint 타입으로 저장된다.


# Repository 사용하기
- Photo 모듈에서 생성한 레포지토리를 사용할 수 있도록 TypeOrmModule.forFeature()로 주입한다.
import { Module } from '@nestjs/common';
import { PhotosService } from './photos.service';
import { PhotosController } from './photos.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Photo } from './entities/photo.entity';
@Module({
imports: [TypeOrmModule.forFeature([Photo])],
controllers: [PhotosController],
providers: [PhotosService],
})
export class PhotosModule {}
# Repository를 사용해서 데이터 추가하기 (with 포스트맨)
- 생성할 데이터를 위한 createPhotoDto 를 생성한다.
- 기본적인 CRUD를 service.ts와 controller.ts에 구현한다.
- 포스트맨에서 메소드와 Body 형식을 raw - JSON으로 설정하고, createPhotoDto와 일치하는 데이터를 보낸다.
//create-photo.dto.ts
export class CreatePhotoDto {
name: string;
description: string;
filename: string;
views: number;
isPublished: boolean;
}
//photos.controller.ts
import { Controller, Get, Param, Delete, Post, Body } from '@nestjs/common';
import { CreatePhotoDto } from './dto/create-photo.dto';
import { PhotosService } from './photos.service';
@Controller('photos')
export class PhotosController {
constructor(private readonly photosService: PhotosService) {}
@Post()
createPhoto(@Body() createPhotoDto: CreatePhotoDto) {
this.photosService.createPhoto(createPhotoDto);
return JSON.stringify({ message: 'Success_creating_photo' });
}
@Get()
findAll() {
return this.photosService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.photosService.findOne(+id);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.photosService.remove(+id);
}
}
//photos.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreatePhotoDto } from './dto/create-photo.dto';
import { Photo } from './entities/photo.entity';
@Injectable()
export class PhotosService {
constructor(
@InjectRepository(Photo)
private photoRepository: Repository<Photo>,
) {}
async createPhoto(createPhoto: CreatePhotoDto): Promise<void> {
await this.photoRepository.save(createPhoto);
}
findAll(): Promise<Photo[]> {
return this.photoRepository.find();
}
findOne(id: number): Promise<Photo> {
return this.photoRepository.findOneBy({ id });
}
async remove(id: number): Promise<void> {
await this.photoRepository.delete(id);
}
}



# 메소드와 data loading 형태
- find()

- findOneBy()

- findBy()

- save() : update 구현
update는 findOneBy로 바꿀 데이터를 불러오고, 불러온 데이터에서 변경할 키값을 새롭게 부여하고, 변경된 데이터를 다시 save한다.
// service
async updateOne(id: number, body) {
const photoOne = await this.photoRepository.findOneBy({ id });
const key = Object.keys(body)[0];
photoOne[`${key}`] = Object.values(body)[0];
await this.photoRepository.save(photoOne);
return photoOne;
}
// controller
@Patch(':id/update')
updateOne(@Param('id') id: string, @Body() body) {
return this.photosService.updateOne(+id, body);
}

# remove 역시, 객체를 넣어서 지운다.
- delete() 는 삭제할 객체의 속성 입력 (2번 데이터 삭제)
- remove() 는 삭제할 객체 자체 입력 (4번 데이터 삭제)
//delete 사용
async remove(id: number): Promise<void> {
await this.photoRepository.delete(id);
}
//remove 사용
async removeByRemove(id: number): Promise<void> {
const targetPhoto = await this.photoRepository.findOneBy({ id });
await this.photoRepository.remove(targetPhoto);
}


'DB > typeORM' 카테고리의 다른 글
TypeORM 다대다 연결 시 관계테이블 이름 커스텀하기 (0) | 2025.01.18 |
---|---|
엔티티(Entity)란 무엇인가? (0) | 2022.12.10 |
시작하기 - Entity 관계 만들기(MySQL Key종류) (0) | 2022.10.19 |
TypeORM Contents (0) | 2022.10.05 |