일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Nest.js
- java
- 반복문
- class
- AWS
- back-end
- spring boot
- node.js
- 개발이 취미인 사람
- kafka
- restful api
- swagger
- component
- 개발자
- Kotlin
- vue
- It
- react
- state
- 코틀린
- Producer
- props
- 조건문
- javascript
- file upload
- SWIFT
- 자바
- 상속
- front-end
- Sequelize
- Today
- Total
개발이 취미인 사람
[Nest.js] Nest.js API 만들기 (5) - TypeORM 개념 및 설치 본문
- 개요
안녕하세요. 이번 시간에는 TypeORM을 Nest.js에 적용하는 시간을 가져 보도록 하겠습니다.
TypeORM은 ORM 기술 중 하나로 "객체와 관계형 데이터 베이스를 매핑(연결)을 통해 객체 모델과 관계형 모델 간 불일치를 해결" 함으로써 객체와 데이터베이스의 변형에 유연하게 사용할 수 있는 기술입니다.
ORM(Object Relational Mapping)
- 설치 및 설정
TypeORM을 사용하기 위해서는 몇 가지 모듈이 필요합니다.
- @nestjs/typeorm - Nest.js에서 TypeORM을 사용하기 위해 연동시켜주는 모듈
- typeorm - 실제 TypeORM(TypeORM은 JavaScript를 지원합니다)
- mysql2 - MySQL 데이터베이스 연결 시 사용
#npm
npm install mysql2 typeorm @nestjs/typeorm
#yarn
yarn add mysql2 typeorm @nestjs/typeorm
TypeORM은 다양한 데이터베이스를 지원합니다.
RDBMS : MySQL / MariaDB / Postgres / CockroachDB / SQLite / Microsoft SQL Server / Oracle / SAP Hana / sql.js
NoSQL : MongoDB
TypeORM 파일 설정
src/configs 폴더를 생성하고 파일 이름은 본인이 편한 이름으로 생성해주시면 됩니다. 저는 typeorm.config.ts로 생성했습니다.
(ts 확장자는 무조건 해주셔야 합니다. 컴파일 시 제외될 수 있습니다.)
typeorm.config.ts 파일 안에는 우리가 실제 연결 시 필요한 설정 값들은 작성합니다.
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
export const typeORMConfig: TypeOrmModuleOptions = {
type: 'mysql', //Database 설정
host: 'localhost',
port: 3306,
username: 'root',
password: '1234',
database: 'Ryan',
entities: ['dist/**/*.entity.{ts,js}'], // Entity 연결
synchronize: true, //true 값을 설정하면 어플리케이션을 다시 실행할 때 엔티티안에서 수정된 컬럼의 길이 타입 변경값등을 해당 테이블을 Drop한 후 다시 생성해준다.
};
위 설정 옵션 중에 synchronize 옵션은 배포 단계에서는 false로 설정해야 합니다.
그렇지 않으면... 데이터베이스가 초기화가 진행돼서 데이터가 전부 없어지는 상황이 발생하게 됩니다...(서비스가... 망할 수 있어요 ㅠㅠ)
설정 파일 연결
우리가 만든 파일 정보를 Nest.js에서 사용하기 위해서는 app.module.ts 파일에 연결해야 합니다.
import {
Module,
NestModule,
MiddlewareConsumer,
RequestMethod,
} from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { typeORMConfig } from './configs/typeorm.config';
import { UserModule } from './user/user.module';
import { AuthMiddleware } from './middleware/auth.middleware';
import { UserController } from './user/user.controller';
@Module({
imports: [
TypeOrmModule.forRoot(typeORMConfig), // TypeORM 설정 파일 연결
UserModule,
],
controllers: [],
providers: [],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(AuthMiddleware)
//exclude 함수는 제외 하고싶은 라우터를 등록합니다.
.exclude({ path: 'user/create_user', method: RequestMethod.POST }) // 유저 생성
.exclude({ path: 'user/user_all', method: RequestMethod.GET }) // 유저 전체 조회
.forRoutes(UserController); // 1.유저 컨트롤러 등록
// .forRoutes('user'); // 2.유저 컨트롤러 경로 등록 -> 위 1번과 동일
}
}
TypeOrmModule과 typeORMConfig 파일 가져와 imports 항목에 추가합니다.
forRoot안에 설정한 파일은 모든 모듈에 적용이 됩니다.
- Entity 생성 및 Repository 연결
지난 시간까지 User를 Memory에 저장을 통해 임시로 진행했었습니다. 이 부분을 실제 TypeORM 엔티티로 변경해보겠습니다.
저는 디렉토리 구조를 아래와 같이 가져갑니다.
Entity 생성
import {
BaseEntity,
Column,
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
Unique,
} from 'typeorm';
@Entity({ name: 'user' })
@Unique(['user_id'])
export class User extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ type: 'varchar', length: 50, comment: '유저 아이디' })
user_id: string;
@Column({ type: 'varchar', length: 255, comment: '유저 비밀번호' })
password: string;
@Column({ type: 'varchar', length: 255, comment: 'salt' })
salt: string;
@Column({ type: 'varchar', length: 30, comment: '유저 이름' })
name: string;
@Column({ type: 'tinyint', comment: '유저 나이' })
age: number;
@CreateDateColumn({ name: 'create_at', comment: '생성일' })
createdAt: Date;
@UpdateDateColumn({ name: 'update_at', comment: '수정일' })
updatedAt: Date;
@DeleteDateColumn({ name: 'delete_at', comment: '삭제일' })
deletedAt?: Date | null;
}
옵션
@Entity - 해당 클래스는 DB user 테이블과 매핑시킬 때 사용
@Unique - 유니크 컬럼을 설정할 때 사용(배열 형태로 원하는 컬럼 값을 지정하면 된다)
@PrimaryGeneratedColumn - uuid 값을 지정하면 해당 컬럼은 uuid 타입으로 설정이 되며, Auto Increment 타입으로 설정
Auto_Increment : @PrimaryGeneratedColumn()
UUID: @PrimaryGeneratedColumn('uuid')
@Column - 해당 클래스 속성과 DB user 테이블 컬럼과 매핑시킬 때 사용
@CreateDateColumn - 데이터가 생성되는 시간을 기록할 때 사용
@UpdateDateColumn - 데이터가 수정되는 시간을 기록할 때 사용
@DeleteDateColumn - 데이터가 삭제되는 시간을 기록할 때 사용(실제 삭제되지 않는다. 백업 서버가 없다면 해당 옵션을 사용!!)
Repository 생성 및 연결
Nest.js는 저장소 패턴(Repository Pattern)을 지원합니다. Repository 계층에서는 DB 작업을 다룹니다.
지난 시간에 Nest.js가 클라이언트 요청을 처리하는 로직을 설명했었습니다.
"1. @Controller -> 2.@Service -> 3. Repository"
@Controller 계층에서는 클라이언트 요청 정보를 처리하고 @Service 계층에서는 비즈니스 로직을 담당하며, Repository 계층에서는 DB 작업을 다룬다고 생각하시면 됩니다.
UserRepository
import { EntityRepository, Repository } from 'typeorm';
import { User } from '../entity/user.entity';
@EntityRepository(User)
export class UserRepository extends Repository<User> {}
연결
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserRepository } from 'src/repository/user.repository';
import { UserController } from './user.controller';
import { UserService } from './user.service';
@Module({
imports: [TypeOrmModule.forFeature([UserRepository])], //UserRepository 등록
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
우리는 UserModule에서 사용해야하기 때문에 UserModule에 UserRepository를 등록합니다.
이렇게 등록하고 UserService에 등록하고 사용하면 됩니다.
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { UserRepository } from 'src/repository/user.repository';
import { CreateUserDto, UpdateUserDto } from './dto/user.dto';
import { User } from 'src/entity/user.entity';
@Injectable()
export class UserService {
//생성자 부분에 가져와 사용한다.
constructor(
@InjectRepository(UserRepository) private userRepository: UserRepository,
) {}
}
여기까지 문제 없이 진하셨다면 UserService 계층에서 Repository에 접근이 가능합니다.
다음 시간에는 기존에 만들었던 API를 변경해보겠습니다.