๐ŸŽ‰ berenickt ๋ธ”๋กœ๊ทธ์— ์˜จ ๊ฑธ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. ๐ŸŽ‰
Back
NestJs
07-TypeORM

1. NestJS์— Typeorm ์„ค์ •

1
yarn add @nestjs/typeorm typeorm pg
2
yarn start:dev

docker-compose up์œผ๋กœ ๋จผ์ € ์ผœ์ฃผ๊ณ , yarn start:dev๋กœ ์‹คํ–‰์‹œํ‚จ๋‹ค.

app.module.ts
1
import { Module } from '@nestjs/common'
2
import { TypeOrmModule } from '@nestjs/typeorm'
3
4
import { AppController } from './app.controller'
5
import { AppService } from './app.service'
6
import { PostsModule } from './posts/posts.module'
7
8
@Module({
9
imports: [
10
PostsModule,
11
TypeOrmModule.forRoot({
12
// ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํƒ€์ž…
13
type: 'postgres',
14
host: '127.0.0.1',
15
port: 5808,
16
username: 'postgres',
17
password: 'postgres',
18
database: 'postgres',
19
// entitiesํด๋”์— ์ž‘์„ฑํ•œ PostsModel ๊ฐ€์ ธ์˜ค๊ธฐ
20
entities: [],
21
synchronize: true,
22
}),
23
],
24
controllers: [AppController],
25
providers: [AppService],
26
})
27
export class AppModule {}

2. Entity๋กœ ํ…Œ์ด๋ธ” ์ƒ์„ฑ

posts/entities/posts.entity.ts๋กœ ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

posts.entity.ts
1
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'
2
3
@Entity()
4
export class PostsModel {
5
@PrimaryGeneratedColumn()
6
id: number
7
8
@Column()
9
author: string
10
11
@Column()
12
title: string
13
14
@Column()
15
content: string
16
17
@Column()
18
likeCount: number
19
20
@Column()
21
commentCount: number
22
}
app.module.ts
1
// ์ƒ๋žต
2
import { PostsModel } from './posts/entities/posts.entity'
3
4
@Module({
5
imports: [
6
PostsModule,
7
TypeOrmModule.forRoot({
8
// ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํƒ€์ž…
9
type: 'postgres',
10
host: '127.0.0.1',
11
port: 5808,
12
username: 'postgres',
13
password: 'postgres',
14
database: 'postgres',
15
// entitiesํด๋”์— ์ž‘์„ฑํ•œ PostsModel ๊ฐ€์ ธ์˜ค๊ธฐ
16
entities: [PostsModel],
17
synchronize: true,
18
}),
19
],
20
controllers: [AppController],
21
providers: [AppService],
22
})
23
export class AppModule {}

3. Repository ์ฃผ์ž…

  • ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ผ์ข…์˜ bridge ์—ญํ•  === Repository
posts.module.ts
1
import { Module } from '@nestjs/common'
2
import { PostsService } from './posts.service'
3
import { PostsController } from './posts.controller'
4
import { TypeOrmModule } from '@nestjs/typeorm'
5
import { PostsModel } from './entities/posts.entity'
6
7
@Module({
8
imports: [
9
/*** ๋ชจ๋ธ์— ํ•ด๋‹นํ•˜๋Š” repostory๋ฅผ ์ฃผ์ž… ==> forFeature
10
* repository : ํ•ด๋‹น ๋ชจ๋ธ์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํด๋ž˜์Šค
11
*/
12
TypeOrmModule.forFeature([PostsModel]),
13
],
14
/** ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์‚ฌ์šฉํ•  ํŒŒ์ผ์„ ์ •์˜
15
* ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์‚ฌ์šฉํ•  ํŒŒ์ผ์„ ์ •์˜,
16
* ํŠน์ • path๋กœ ์š”์ฒญ์ด ์˜ค๋ฉด ๋ผ์šฐํŒ…ํ•ด์ฃผ๋Š” ์—ญํ• 
17
*
18
* PostsController() ===> ์ธ์Šคํ„ด์Šคํ™”
19
* PostsController ===> ํด๋ž˜์Šค ๊ทธ ์ž์ฒด
20
* ์ž˜ ๋ณด๋ฉด, ์ธ์Šคํ„ด์Šค๊ฐ€ ์•„๋‹Œ ํด๋ž˜์Šค ๊ทธ ์ž์ฒด๋ฅผ ๋„ฃ์—ˆ๋‹ค
21
* ์™œ๋ƒํ•˜๋ฉด IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ, ์ˆ˜์ •, ์‚ญ์ œํ•˜๊ธธ ๋ฐ”๋ผ๋‹ˆ๊นŒ
22
*/
23
controllers: [PostsController],
24
/** ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ฃผ์ž…ํ•  ๊ฐ’๋“ค์„ providers ์•ˆ์— ์ •์˜
25
* PostsService๋Š” ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ •์˜๋‹ค.
26
* ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋กœ์ง์„ ์ž‘์„ฑํ•˜๋Š” ํด๋ž˜์Šค === Service
27
*
28
* ์„œ๋น„์Šค๊ฐ€ ์•„๋‹ˆ๋”๋ผ๋„ ์ฃผ์ž…ํ•ด์•ผํ•  ํด๋ž˜์Šค๋“ค์€
29
* ์ „๋ถ€ providers ์•ˆ์— ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.
30
*
31
* porviders ์•ˆ์— ๋“ฑ๋ก๋œ ๋ชจ๋“  ํด๋ž˜์Šค๋“ค์€ ์ธ์Šคํ„ด์Šคํ™” ์—†์ด
32
* IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์˜์กดํ•˜๋ฉด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
33
*/
34
providers: [PostsService],
35
})
36
export class PostsModule {}
posts.service.ts
1
// posts.service.ts
2
import { Injectable, NotFoundException } from '@nestjs/common'
3
import { InjectRepository } from '@nestjs/typeorm'
4
import { Repository } from 'typeorm'
5
import { PostsModel } from './entities/posts.entity'
6
7
// ์ƒ๋žต
8
9
@Injectable()
10
export class PostsService {
11
constructor(
12
@InjectRepository(PostsModel)
13
private readonly postsRepository: Repository<PostsModel>,
14
) {}
15
16
// ์ƒ๋žต
17
}

4. Find() ์‚ฌ์šฉํ•ด ๋‹ค์ˆ˜ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ

posts.service.ts
1
// posts.service.ts ์ƒ๋žต
2
async getAllPosts() {
3
return this.postsRepository.find()
4
}

5. FindOne() ์‚ฌ์šฉํ•ด ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ๋งŒ ์ฐพ๊ธฐ

posts.service.ts
1
// posts.service.ts ์ƒ๋žต
2
async getPostById(id: number) {
3
const post = await this.postsRepository.findOne({
4
// PostsModel์˜ id๊ฐ€ ์ž…๋ ฅ๋ฐ›์€ id์™€ ๊ฐ™์€์ง€ ํ•„ํ„ฐ๋ง
5
where: {
6
id,
7
},
8
})
9
if (!post) {
10
throw new NotFoundException()
11
}
12
return post
13
}

6. Create() ์‚ฌ์šฉํ•ด ์ƒˆ ๋ฐ์ดํ„ฐ ์ƒ์„ฑํ•˜๊ธฐ

posts.service.ts
1
/**
2
* 1) create : ์ €์žฅํ•  ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
3
* 2) save : ๊ฐ์ฒด๋ฅผ ์ €์žฅ (create aใ…”์„œ๋“œ์—์„œ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋กœ)
4
*/
5
async createPost(author: string, title: string, content: string) {
6
const post = this.postsRepository.create({
7
author,
8
title,
9
content,
10
likeCount: 0,
11
commentCount: 0,
12
})
13
14
const newPost = await this.postsRepository.save(post)
15
16
return newPost
17
}

7. Save()๋กœ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ

posts.service.ts
1
/** save์˜ 2๊ฐ€์ง€ ๊ธฐ๋Šฅ
2
* 1) ๋งŒ์•ฝ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด(id ๊ธฐ์ค€) ์ƒˆ๋กœ ์ƒ์„ฑํ•œ๋‹ค.
3
* 2) ๋งŒ์•ฝ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด(๊ฐ™์€ id์˜ ๊ฐ’์ด ์กด์žฌํ•œ๋‹ค๋ฉด) ์กด์žฌํ•˜๋˜ ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.
4
*/
5
async updatePost(postId: number, author: string, title: string, content: string) {
6
const post = await this.postsRepository.findOne({
7
where: { id: postId },
8
})
9
10
if (!post) throw new NotFoundException()
11
if (author) post.author = author
12
if (title) post.title = title
13
if (content) post.content = content
14
15
const newPost = await this.postsRepository.save(post)
16
return newPost
17
}

8. Delete()๋กœ ๋ฐ์ดํ„ฐ ์‚ญ์ œํ•˜๊ธฐ

1
async deletePost(postId: number) {
2
const post = await this.postsRepository.findOne({
3
where: { id: postId },
4
})
5
6
if (!post) throw new NotFoundException()
7
8
await this.postsRepository.delete(postId)
9
10
return postId
11
}