✅ TypeORM 이란?
- TypeORM은 node.js에서 실행되고 TypeScript로 작성된 객체 관계형 매퍼 라이브러리이다
- 객체와 관계형 데이터베이스의 데이터를 자동으로 변형 및 연결하는 작업이다
- ORM을 이용한 개발은 객체와 데이터베이스의 변형에 유연하게 사용할 수 있다
✅ TypeORM 설치
npm install --save @nestjs/typeorm typeorm mysql2
✅ NestJS + MySQL 연결
방법1️⃣. app.module.ts 파일 설정
// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: '본인 데베 유저이름', // ex) root
password: '본인 데베 비번', // ex) test
database: '본인 데베 이름', // ex) test
entities: [], // 사용할 entity의 클래스명을 넣어둔다. 밑에서 Cat entity만든 후 추가할것
synchronize: true, // false로 해두는 게 안전하다.
}),
],
})
export class AppModule {}
방법2️⃣. ormconfig.json 파일 생성, 설정
2-1) ormconfig.json 파일 생성
// ormconfig.json
{
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "root",
"database": "test",
"entities": ["dist/**/*.entity{.ts,.js}"],
"synchronize": true
}
2-2) app.module.ts 파일 설정
// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [TypeOrmModule.forRoot()],
})
export class AppModule {}
✅ Entity 생성 및 연결
1️⃣ cats.entity.ts 파일 생성
- @Entity() : Cat 클래스가 엔티티임을 나타내는데 사용
- @PrimaryGeneratedColumn() : 그 클래스의 대표값(id, 주민번호 ,,) 열임을 나타내는데 사용
- @Column() : 데이터베이스에 있는 열을 나타내는데 사용, db와 똑같이 선언해줘야함
// cats/entity/cats.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Cat {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
age: number;
@Column()
breed: string;
@Column({ default: true })
isActive: boolean;
}
2️⃣ app.module.ts에 cats.entity 추가
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'test',
entities: [Cat], // 여기랑
synchronize: true,
}),
CatsModule // 여기 추가 !!
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
3️⃣ cats.module.ts에서 cats.entity 사용할 수 있게 소스 추가
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Cat } from './entity/cats.entity';
@Module({
imports: [TypeOrmModule.forFeature([Cat])],
exports: [TypeOrmModule],
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {}
4️⃣ cats.service.ts에 catsRepository를 생성하여 data를 핸들링할 수 있게 (Repository Injection))
- Repository : 엔티티 개체와 함께 작동하며 CRUD 기능 등을 처리한다
- @EntityRepositorty() : 해당 클래스를 사용자 정의 저장소로 선언하는데 사용됨
- @InjectRepository() : 이 Service에서 catsRepository를 이용한다고 알려주는,,
// cats/cats.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
// import { Repository } from 'typeorm';
import { Cat } from './entity/cats.entity';
import { getConnection } from "typeorm";
@Injectable()
export class CatsService {
constructor(
@InjectRepository(Cat) // Cat이라는 엔티티를 Repository로 사용할 수 있게됨
private catsRepository: Repository<Cat>,
) {}
findAll(): Promise<Cat[]> {
return this.catsRepository.find();
}
findOne(id: string): Promise<Cat> {
return this.catsRepository.findOne({ where: { id } }); // typeORM 9.0.0버전에서는 이렇게
}
async create(cat: Cat): Promise<void> {// 처리가 완료가 된 다음에 return 할 수 있도록
await this.catsRepository.save(cat);
}
async remove(id: number): Promise<void> {
await this.catsRepository.delete(id);
}
async update(id: number, cat: Cat): Promise<void> {
const existCat = await this.catsRepository.findOne(id);
if(existCat){
// await getConnection()
await this.catsRepository // typeORM 9.0.1 버전에서는 이렇게 진행
.createQueryBuilder()
.update(Cat)
.set({
name: cat.name,
age: cat.age,
breed: cat.breed
})
.where("id = :id", { id })
.execute();
}
}
}
5️⃣ cats.controller.ts 작성
// cats/cats.controller.ts
import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './entity/cats.entity';
@Controller('cats')
export class CatsController {
constructor(private catsService: CatsService){};
@Get()
findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
@Get(':id')
findOne(@Param('id')id: string): string {
return `This action returns a #${id} cat`;
}
@Post()
create(@Body() cat: Cat){
return this.catsService.create(cat);
}
@Put(':id')
update(@Param('id')id: number, @Body() cat: Cat){
this.catsService.update(id, cat);
return `This action updates a #${id} cat`;
}
@Delete(':id')
remove(@Param('id')id: number){
this.catsService.remove(id);
return `This action removes a #${id} cat`;
}
}
❓❓ DTO vs Entity
위처럼 그냥 Entity를 바로 넣어주면 되지 않나 ! 왜 DTO가 필요했던거지? 라는 의문이 들었음
밑에 코드를 예시로 들면, (이때 Cat은 cat.entity.ts 즉 엔티티 객체임)
@Get()
findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
- Entity 객체를 위처럼 View에 직접 전달할 수 있지만, Cat의 민감한 정보가 외부에 노출되는 보안문제가 생길 수 있다.
- 불필요한 데이터를 전부 View에서 받을 수 있다.
- View에서 Model의 메서드를 직접적으로 호출하거나, 상태를 변결시킬 위험도 존재해 Model과 View가 강하게 결합되어 View의 요구사항 변화가 Model에 영향을 끼치기 쉽다
https://overcome-the-limits.tistory.com/648 (참고)
요약
참고
https://codegear.tistory.com/67?category=991389
https://velog.io/@suasue/NestJS-TypeORM-Mysql-%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0
'Node.js > Nest.js' 카테고리의 다른 글
[NestJS] 로그인 기능 구현, JWT (0) | 2022.10.12 |
---|---|
[NestJS] 회원가입 기능 구현 (0) | 2022.10.11 |
[NestJS] Nest의 미들웨어(Middleware) (0) | 2022.10.10 |
[NestJS] Controller에서 Request를 받는 방법 (0) | 2022.10.09 |
[NestJS] NestJS 로직 흐름 / Module, Controller, Service 자동 생성 (0) | 2022.10.09 |