NestJS TypeORM의 Many to Many 구현 1- 셋팅 및 각 테이블 생성

 안녕하세요. 이번에는 nestjs의 프레임 워크와 TypeORM을 이용하여 다대다(Many to Many)관계도를 구축할려고 합니다. 다대다 관계를 구축할때 Record 생성, 수정, 삭제는 다음 글에서 작성하고 지금은 DB Table을 생성하도록 하겠습니다. DBMS은 MySQL을 사용할 것입니다.


참고로 Many to Many(다대다) 구조에 대해서 잘 모르시는 분들은 아래 링크를 참고해 주시기 바랍니다.

링크 : SQL 관계도 Many to Many(다대다 관계)


그리고 위 글에서는 NestJS와 TypeORM을 이용한 Many To Many 테이블을 구축하는 것입니다. NestJS가 설치되어 있어야 합니다. 설치가 안되어 있으면 아래 링크를 참고해 주시기 바랍니다.

NestJS설치법

링크1 : nest js - install & Create Project from Linux or Ubuntu


NestJS에 MySQL셋팅법

링크2 : nest js -5 Connect to DataBase(mysql) with TypeORM


링크2에서 블로그에서 작성할 코드와 다른점은 '.env'파일을 사용한다는 것입니다. 환경설정변수를 저장한 문서인데 쉽게 말하자면 민감한 정보를 저장한 파일 입니다. 자세한 이야기는 블로그 글을 작성하고 링크를 달아두도록 하겠습니다. (아니면 검색하셔도 됩니다.)


먼저 npm 설치가 필요합니다.

$ npm i dotenv



사진1) .env파일 생성

// TypeORM의 option 설정
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
require('dotenv').config() // .env파일 적용을 위해 npm 추가

// TypeORM과 DataBase를 연결하기 위한 셋팅
export const typeOrmConfig:TypeOrmModuleOptions = {
type: 'mysql', // 데이터베이스 타입
host: process.env.DATABASE_HOST, // 주소
port: Number(process.env.DATABASE_PORT), // 데이터베이스 포스트
username: process.env.DATABASE_USER, // 데이터베이스 소유자 이름
password: process.env.DATABASE_PASS, // 데이터베이스 비밀번호
database: process.env.DATABASE_DB, // 데이터베이스 이름
autoLoadEntities: true, // 자동으로 entities를 DB에 배포
synchronize: true // 동기화(Production에서는 false으로 지정해야함)
};



이제 NestJS을 실행하면 local에 있는 MySQL에 접속하게 됩니다. 그럼 이제 어떤식으로 Many To Many를 구현할 것인지 확인하겠습니다.  여기서 진행할수 있는 방법이 2가지 인데 직접 JoinTable을 만드는 방법과 자동으로 TypeORM으로 구현하는 방법 입니다. 두번째 방법은 자동으로 구현되지만 JoinTable에 추가적인 컬럼을 넣을수 없습니다. 따라서 이번 블로그에서는 첫번째 방법을 사용하도록 하겠습니다.


사진2) 다대다 관계

만들 다대다 관계는 유저와 책의 관계입니다. 유저가 책에 대한 리뷰를 적습니다. 1명의 유저는 여러권의 책에 대해서 리뷰를 작성할수 있습니다. 또한 1권의 책도 여러명한테 리뷰를 받을수 있습니다.


user(Many) -> joinTable(One)

book(Many) -> joinTable(One)


이제 이걸 구현할 코드를 만들도록 하겠습니다. 먼저 유저를 만들도록 하겠습니다.


사진3) src안에 users폴더 생성

사진 3과 같이 폴더를 구성하시고 user.entity.ts에 클래스 설정을 합니다.

// users.entity.ts : src/users/entities
import { Column, CreateDateColumn, PrimaryGeneratedColumn, Entity } from 'typeorm';

@Entity()
export class User {
@PrimaryGeneratedColumn()
id: Number;

@Column({
nullable: false,
})
full_name: string;

@CreateDateColumn({ readonly: true })
created_at: Date;
}


이제 모듈로 들어가서 아래 코드와 같이 직성해 줍니다.
// users.module.ts : src/users

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';

@Module({
imports:[TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService]
})
export class UsersModule {}


사진4) NestJS실행 후 Table 생성

마찬가지로 book폴더를 만든다음 위의 코드처럼 book.module.ts을 수정하고 동일하게 적용해 줍니다.



사진5) book폴더 생성

// book.entity.ts : src/book/entities
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
} from 'typeorm';

@Entity()
export class Book {
@PrimaryGeneratedColumn()
id: Number;

@Column({
nullable: false,
})
comment: string;

@CreateDateColumn({ readonly: true })
created_at: Date;
}


 JoinTable을 만들겠습니다. JoinTable의 명칭은 user_book_join이라고 명명하겠습니다. 그리고 해당 entity는 'src/book/entities'폴더 안에 저장하도록 하겠습니다.


// user_book_join.entity.ts : src/book/entities

import { Column, CreateDateColumn, Entity, PrimaryColumn } from 'typeorm';

@Entity()
export class User_Book_Join {
// 여기서 PrimaryColumn은 userId와 bookId의 조합이다.
@PrimaryColumn({
nullable: false,
})
userId: number;

@PrimaryColumn({
nullable: false,
})
bookId: number;

@Column({
nullable: false,
})
book_review: string;

@CreateDateColumn({ readonly: true })
created_at: Date;
}


// users.module.ts : src/book

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BookController } from './book.controller';
import { BookService } from './book.service';
import { Book } from './entities/book.entity';
import { User_Book_Join } from './entities/user_book_join.entity';

@Module({
// TypeOrmModule.forFeature안에 User_Book_Join을 추가한다.
imports: [TypeOrmModule.forFeature([Book, User_Book_Join])],
controllers: [BookController],
providers: [BookService],
})
export class BookModule {}



사진7) MySQL의 Table


위 JoinTable에서 유저는 1개의 책에 대해서 한번만 리뷰를 달수 있습니다. 만약 같은 책에 대해서 다른 리뷰를 달게되면 Prime Column이 중복이 되기때문에 MySQL에서 거부하게 됩니다.

이런 방법으로 테이블을 작성하고 각 테이블간의 관계를 TypeORM으로의 작성은 다음 글에 작성하도록 하겠습니다.




댓글

이 블로그의 인기 게시물

Lesson 12_1 프로퍼티 노드(Property Node)

DAQ로 전압 측정하기-2

Lesson 12_2 참조를 이용한 프로퍼티노드(Property Node)