NestJS-Typeorm 사용해보기

jaegeunsong97·2023년 11월 14일
0

NestJS

목록 보기
8/37
post-custom-banner

🖊️TypeORM 설정

TypeORM을 사용할 수 있도록 cli 입력 후 설치

// @nestjs/typeorm에서 typeorm를 사용
yarn add @nestjs/typeorm typeorm pg
  • app.module.ts

TypeORM 모듈을 imports 해주기

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PostsModule } from './posts/posts.module';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    PostsModule,
    TypeOrmModule.forRoot({
      // Object 입력 -> VSCode에서 Postgres와 연결할 때 사용한 정보와 동일
      type: 'postgres', // 데이터베이스 타입
      host: '127.0.0.1',
      port: 5432,
      username: 'postgres',
      password: 'postgres',
      database: 'postgres',
      entities: [
        // 데이터베이스와 연동될 Model
      ],
      synchronize: true, // Nest.js의 TypeORM 코드와 데이터베이스의 싱크를 자동으로 맞출거냐? / PROD인 경우에는 false로
    }) // TypeORM과 Nest.js 연결 메소드
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

실행 시 에러가 없어야 한다.


🖊️Entity로 테이블 생성

SQL cmd로 사용해서 테이블을 생성하는 것이 아닌 TypeORM 기반으로 테이블을 생성해보자.

  • posts/entities/posts.entity.ts
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";

@Entity()
export class PostsModel { // TypeORM이 app.module.ts에 해당 정보들을 기반으로 DB에 생성한다.
     @PrimaryGeneratedColumn() // PK 이면서 자동증가전략
     id: number;

     @Column()
     author: string;

     @Column()
     title: string;

     @Column()
     content: string;

     @Column()
     likeCount: number;

     @Column()
     commentCount: number;
}

다음과 같이 코드로 작성을 하고 Entity()를 붙이면, TypeORM이 데이터베이스에 알아서 생성을 해준다. 단 PostsModule을 app.module.ts에 등록을 해야한다.

  • app.module.ts
entities: [
	// 데이터베이스와 연동될 Model
	PostsModel,
],

🖊️Repository 주입하기

let posts: PostModel[] = [
     {
       id: 1,
       author: 'newjeans_minji',
       title: '뉴진스 민지',
       content: '메이크업 고치고 있는 민지',
       likeCount: 100000,
       commentCount: 999,
     },
     {
       id: 2,
       author: 'newjeans_herin',
       title: '뉴진스 헤린',
       content: '춤추고 있는 헤린',
       likeCount: 100000,
       commentCount: 999,
     },
     {
       id: 3,
       author: 'newjeans_daniel',
       title: '뉴진스 다니엘',
       content: '노래부르는 다니엘',
       likeCount: 100000,
       commentCount: 999,
     },
   ]

기존에 리스트를 만들어서 메모리에다가 정보들을 저장했습니다. 따라서 이제는 메모리가 아닌 SSD(데이터베이스)에 저장을 해보겠습니다. 먼저 PostsModel에서 Repository를 주입받아야 합니다.

  • posts/posts.module.ts
import { Module } from '@nestjs/common';
import { PostsService } from './posts.service';
import { PostsController } from './posts.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PostsModel } from './entities/posts.entity';

@Module({
  imports: [
    // PostsModule에서 사용할 Repository 등록
    TypeOrmModule.forFeature([ // forFeature(): 주입
      // 불러오고 싶은 Model을 넣어주면 된다.
      PostsModel,
    ]), 
  ],
  controllers: [PostsController],
  providers: [PostsService],
})
export class PostsModule {}

코드의 의미는 PostsModule이라는 곳에서 PostsModel의 Repository를 사용한다는 의미입니다. 그리고 posts.service.ts로 이동후 IoC에서 DI를 하는 코드를 작성합니다.

@Injectable()
export class PostsService {

     constructor(
          @InjectRepository(PostsModel) // TypeORM으로 주입되는 Repository라는 명시
          private readonly postsRepository: Repository<PostsModel>
     ) {}
     
  	 .
     .

🖊️TypeORM의 주요 메소드

find()

@Injectable()
export class PostsService {

     constructor(
          @InjectRepository(PostsModel) // TypeORM으로 주입되는 Repository라는 명시
          private readonly postsRepository: Repository<PostsModel>
     ) {}

     async getAllPosts() {
          return await this.postsRepository.find();
     }
   	 .
     .

find()는 모두 가져오는 TypeORM 함수입니다. 따라서 DB의 모든 데이터를 들고 옵니다. 또한 Repository와의 통신은 전부 비동기 통신을 하기 때문에 async와 await틑 붙입니다.

findOne()

async getPostById(id: number) {
	const psot = await this.postsRepository.findOne({
    	// Object
    	where: {
      		id,
    	},
  	});
  	if (!post) throw new NotFoundException();
    return post;
}

create()

보편적으로 create()로 id가 없는 객체를 생성하고, 해당 객체를 save()해서 id를 가지고 있는 객체를 만듭니다.

async createPost(author: string, title: string, content: string) {
  	// 1) create -> 저장할 객체를 생성한다. -> 저장할 객체를 생성하는 것이기 때문에 동기
  	// 2) save -> 객체를 저장한다. (create 메소드에서 생성한 객체로) -> 비동기
    const post = this.postsRepository.create({
        // Object
        author,
        title,
        content,
        likeCount: 0,
        commentCount: 0,
    });

    // post는 id가 없다. newPost는 id가 있다.
    const newPost = await this.postsRepository.save(post);
    return newPost;
}

save()

async updatePost(postId: number, author: string, title: string, content: string) {
  	// save 기능
  	// 1) 만약에 데이터자 존재하지 않으면, (id 기준으로) 새로 생성한다.
  	// 2) 만약에 데이터가 존재한다면 (같은 id의 값이 존재한다면) 존재하던 값을 업데이트 한다.
    const post = await this.postsRepository.findOne({
        where: {
          	id: postId,
        },
    });
    if (!post) throw new NotFoundException();
    if (author) post.author = author;
    if (title) post.title = title;
    if (content) post.content = content;

    const newPost = await this.postsRepository.save(post); // 여기서는 post가 존재하기 때문에 save()의 2번째 기능인 update를 한다.
    return newPost;
}

delete()

async deletePost(postId: number) {
    const post = await this.postsRepository.findOne({
        where: {
          	id: postId,
        },
    });
    if (!post) throw new NotFoundException();
    await this.postsRepository.delete(postId);
    return postId;
}
profile
블로그 이전 : https://medium.com/@jaegeunsong97
post-custom-banner

0개의 댓글