TypeORM을 사용할 수 있도록 cli 입력 후 설치
// @nestjs/typeorm에서 typeorm를 사용
yarn add @nestjs/typeorm typeorm pg
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 {}
실행 시 에러가 없어야 한다.
SQL cmd로 사용해서 테이블을 생성하는 것이 아닌 TypeORM 기반으로 테이블을 생성해보자.
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에 등록을 해야한다.
entities: [
// 데이터베이스와 연동될 Model
PostsModel,
],
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를 주입받아야 합니다.
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>
) {}
.
.
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;
}