🌈 NestJs에서 typeORM을 사용하는 이유는?
- 통합성: NestJS는 TypeScript 기반의 프레임워크로, TypeORM은 TypeScript 및 JavaScript에서 사용할 수 있는 ORM입니다. 이 두 기술의 통합성이 높아, NestJS에서 TypeORM을 사용하면 일관된 개발 경험을 제공합니다.
- 객체 지향 프로그래밍: TypeORM은 데이터베이스 테이블을 클래스로 모델링하여 객체 지향 프로그래밍을 가능하게 합니다.
- 강력한 쿼리 빌더: TypeORM은 쿼리 빌더를 제공하여 복잡한 쿼리를 직관적인 방식으로 작성할 수 있습니다. 이를 통해 SQL 쿼리를 직접 작성하지 않아도 되며, 코드의 가독성과 유지 관리성이 향상됩니다.
- 데코레이터 및 메타데이터: TypeORM은 데코레이터를 활용하여 엔티티와 컬럼을 정의합니다. 이를 통해 코드의 간결함과 가독성을 유지하면서도 데이터베이스 스키마를 정의할 수 있습니다.
- 마이그레이션 지원: TypeORM은 데이터베이스 스키마 변경을 안전하게 관리할 수 있는 마이그레이션 기능을 제공합니다. 이를 통해 팀원들과 협업하거나, 프로덕션 환경에서의 변경 사항을 안전하게 적용할 수 있습니다.
- 다양한 데이터베이스 지원: TypeORM은 다양한 데이터베이스 시스템을 지원합니다. 이를 통해 여러 데이터베이스 시스템에 쉽게 대응하거나, 기존 데이터베이스와의 통합을 원활하게 진행할 수 있습니다.
NestJS에서 TypeORM을 사용하면 이러한 이점들을 활용하여 데이터베이스와의 상호 작용을 더욱 간편하게 처리할 수 있습니다. 또한, 코드의 일관성을 유지하면서도 유연하게 데이터베이스를 다룰 수 있어, 개발 효율성이 크게 향상됩니다.
🔨 mysql 설치하기
mysql이 설치되지 않으신 분은 아래의 글을 참조하여 설치하시기 바랍니다.
https://develop-const.tistory.com/20
프로젝트 생성하기
NestJS CLI를 사용하여 새 프로젝트를 생성합니다.
nest new project-name
필요한 패키지 설치
TypeORM 및 MySQL을 사용하려면 관련 패키지를 설치해야 합니다.
npm install --save @nestjs/typeorm typeorm mysql2
typeorm설정하기
env파일로 빼도 되지만 간단한 실습을 위해 appModule에 바로 작성하겠습니다.
[ app.module.ts ]
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BooksModule } from './books/books.module';
import { BookEntity } from './books/entities/book.entity';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: '1234',
database: 'test',
synchronize: true,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
- TypeOrmModule.forRoot({ ... }): TypeORM 설정을 초기화합니다. forRoot() 메서드는 TypeORM 모듈을 초기화하는 데 필요한 설정 객체를 반환합니다.
- type: 사용할 데이터베이스 종류를 지정합니다. 이 경우 mysql을 사용합니다.
- host, port: 데이터베이스 서버의 호스트 이름과 포트 번호를 지정합니다.
- username, password: 데이터베이스 서버에 로그인하기 위한 사용자 이름과 비밀번호를 지정합니다.
- database: 사용할 데이터베이스 이름을 지정합니다.
- entities: 사용할 엔티티 클래스를 지정합니다. 이 경우 BookEntity를 사용합니다.
- synchronize: 엔티티와 데이터베이스 테이블을 자동으로 동기화할지 여부를 지정합니다. 이 경우 true로 설정하여 자동 동기화를 활성화합니다. 개발모드에서만 사용해야합니다.
books 파일 생성하기
NestJS CLI를 사용하여 BooksController, BooksService, BookEntity, CreateBookDto, UpdateBookDto와 같은 필수적인 파일들을 생성해줍니다.
nest g resourse books
[ app.module.ts ]
entities: [BookEntity]: TypeORM이 사용할 엔티티 클래스를 지정합니다. 이 경우 BookEntity 엔티티를 사용합니다.
BooksModule도 사용하기 위해 import 해줍니다.
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BooksModule } from './books/books.module';
import { BookEntity } from './books/entities/book.entity';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: '1234',
database: 'test',
entities: [BookEntity],
synchronize: true,
}),
BooksModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
[ book.entity.ts ]
@Entity({ name: 'book' })
export class BookEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
author: string;
@Column()
name: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
@DeleteDateColumn()
deletedAt: Date;
}
- @Entity({ name: 'book' }): { name: 'book' } 옵션을 사용하여 테이블 이름을 지정할 수 있습니다.
- @PrimaryGeneratedColumn(): id 필드를 정의하고, 자동으로 증가하는 기본키(primary key)를 설정합니다.
- @Column(): author, name 필드를 정의합니다. @Column() 데코레이터를 사용하여 열(column)을 정의하고, 해당 필드의 데이터 타입을 지정합니다. 이 경우, author와 name 필드는 각각 string 타입입니다.
- @CreateDateColumn(): 생성될 때 자동으로 생성일자(createdAt)를 기록합니다.
- @UpdateDateColumn(): 업데이트될 때 자동으로 업데이트 일자(updatedAt)를 기록합니다.
- @DeleteDateColumn(): 삭제될 때 자동으로 삭제 일자(deletedAt)를 기록합니다. 이렇게 하면 실제로 데이터를 삭제하지 않고, 삭제된 데이터를 추적할 수 있습니다.
이러한 방식으로 TypeORM을 사용하여 엔티티를 정의하면, 데이터베이스 테이블과 매핑되는 객체를 쉽게 생성하고, 데이터를 조작할 수 있습니다. TypeORM은 엔티티를 생성하고, 데이터를 조작하는 데 필요한 다양한 기능을 제공하기 때문에, 데이터베이스 작업을 보다 쉽게 수행할 수 있습니다.
[ books.service.ts ]
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { BookEntity } from './entities/book.entity';
@Injectable()
export class BooksService {
constructor(@InjectRepository(BookEntity)
private booksRepository: Repository<BookEntity>) { }
async create(book: BookEntity): Promise<BookEntity> {
const newBook = this.booksRepository.create(book);
return await this.booksRepository.save(newBook);
}
async findAll(): Promise<BookEntity[]> {
return this.booksRepository.find();
}
async findOne(id: number): Promise<BookEntity> {
return await this.booksRepository.findOne({
where: {
id
}
});
}
async update(id: number, book: BookEntity): Promise<number> {
await this.booksRepository.update(id, book);
return id
}
async remove(id: number): Promise<number> {
await this.booksRepository.delete(id);
return id
}
}
- @InjectRepository(BookEntity): BookEntity 엔티티를 사용하기 위해, booksRepository 멤버 변수에 TypeORM Repository 객체를 주입합니다. 이 객체는 데이터베이스 조작을 수행하기 위해 사용됩니다.
- async create(book: BookEntity): Promise<BookEntity>: book 매개변수는 생성할 책의 정보가 들어 있는 BookEntity 객체입니다. 이 메서드에서는 booksRepository.create()를 사용하여 새로운 엔티티 객체를 생성한 후, booksRepository.save()를 사용하여 데이터베이스에 저장합니다.
- async findAll(): Promise<BookEntity[]>: booksRepository.find()를 사용하여 데이터베이스에서 모든 책을 조회합니다.
- async findOne(id: number): Promise<BookEntity>: booksRepository.findOne()을 사용하여 데이터베이스에서 특정한 책을 조회합니다.
- async update(id: number, book: BookEntity): Promise<number>: booksRepository.update()를 사용하여 데이터베이스에서 특정한 책을 업데이트합니다.
- async remove(id: number): Promise<number>: booksRepository.delete()를 사용하여 데이터베이스에서 특정한 책을 삭제합니다.
[ books.controller.ts ]
books.controller.ts 파일은 HTTP 요청을 수신하고, BooksService를 호출하여 요청을 처리한 후, 클라이언트에게 응답을 반환하는 컨트롤러입니다.
@Controller('books')
export class BooksController {
constructor(private booksService: BooksService) { }
@Post()
async create(@Body() book: BookEntity): Promise<BookEntity> {
return await this.booksService.create(book);
}
@Get()
async findAll(): Promise<BookEntity[]> {
return this.booksService.findAll();
}
@Get(':id')
async findOne(@Param('id') id: string): Promise<BookEntity> {
return this.booksService.findOne(+id);
}
@Put(':id')
async update(@Param('id') id: string, @Body() book: BookEntity): Promise<number> {
return this.booksService.update(+id, book);
}
@Delete(':id')
async remove(@Param('id') id: string): Promise<number> {
return this.booksService.remove(+id);
}
}
데코레이터에 대해 설명이 필요하다면 아래의글을 참고해주세요.
https://develop-const.tistory.com/6
[ books.module.ts ]
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BooksService } from './books.service';
import { BooksController } from './books.controller';
import { BookEntity } from './entities/book.entity';
@Module({
imports: [TypeOrmModule.forFeature([BookEntity])],
controllers: [BooksController],
providers: [BooksService]
})
export class BooksModule { }
TypeOrmModule.forFeature([BookEntity])는 TypeOrmModule에서 BookEntity 엔티티를 사용하기 위한 설정입니다.
postman을 사용한테스트
postman이 설치되어있지 않다면 아래의 사이트에 접속하셔서 다운받아주세요!
[ post ]
[ get ]
[ put ]
[ delete ]
다음 시간에는 typeorm을 사용하여 인증관련해서 다뤄보겠습니다.
'nest js' 카테고리의 다른 글
NestJs 회원가입(비밀번호 암호화), 로그인 구현하기 (3) | 2023.04.14 |
---|---|
NestJs에서 환경변수 (0) | 2023.04.13 |
NestJs 프로젝트에서 Swagger 사용하기 (0) | 2023.04.07 |
NestJs Guard에 대해 알아보자 (0) | 2023.04.07 |
NestJs Custom decorator에 대해 알아보자 (0) | 2023.04.07 |