React+REST API 게시판 구현/BE - TypeORM

IDEA에서 DataGrip 연결하기 + entity 설계

덕구공 2021. 9. 17. 14:15

참고

https://eastflag.co.kr/fullstack/rest-with-nodejs/node-rest_entity/

 

angular, react, vue 등의 최신프런트엔드로 풀스택 개발

백엔드는 spring boot, Node로 프런트엔드는 react, angular, vue 의 최신프런트엔드를 사용하여 풀스택사이트 개발!

eastflag.co.kr

IDEA + DataGrip

 

DataGrip 사용법 + Docker

Docker에 Local Maria DB 구동 https://duckgugong.tistory.com/220 개발환경 백엔드 개발툴 - IntelliJ http://www.jetbrains.comwww.jetbrains.com/idea/download/#section=windows Download IntelliJ IDEA: The..

duckgugong.tistory.com

  • 위 링크에서 DataGrip에 DB를 구축하고 아래처럼 board와 comment 테이블을 만들었다.

  • 이 두개의 테이블을 entity를 설계해서 만들어보자.
  • 우선 typeORM 설정이 되어있지 않다면 아래 링크를 참고하여 설정을 하자
  • https://duckgugong.tistory.com/224
 

typeORM 설정

참고 https://eastflag.co.kr/fullstack/rest-with-nodejs/node-rest_typeorm/ angular, react, vue 등의 최신프런트엔드로 풀스택 개발 백엔드는 spring boot, Node로 프런트엔드는 react, angular, vue 의 최신..

duckgugong.tistory.com

  • IDEA에서 쉬프트를 두번 눌러서 나오는 검색창에 database를 검색하고 클릭하면 우측에 database 탭이 보일 것이다.
  • 그러고 위에서 구축한 MariaDB의 정보를 넣고 연결하자.

  • 연결을 끝내면 IDEA에서 DataGrip에서 구축한 DB를 확인할 수 있다!

'

  • 우선 board 테이블과 comment 테이블을 drop하자.

typeORM 어노테이션

@Entity()

  • 클래스 위에 붙이는 테이블에 해당하는 어노테이션이다.
  • 만약 테이블 명을 변경하고자 한다면 괄호 안에 명시한다. 

@Column()

  • 테이블 필드를 생성해주는 어노테이션. column을 만들어주는 어노테이션이다.
  • 속성은 () 안에 명시하는데 json 속성으로 명시한다
  • 만약 varchar(100)인 필드이면 아래처럼 써준다
@Column({length: 100})

@PrimaryGeneratedColumn()

  • primary key를 생성해주는 어노테이션

@CreateDateColumn()

  • current_timestamp를 설정해주는 어노테이션

@UpdateDateColumn()

  • on update current_timestamp를 설정해주는 어노테이션

@OneToMany

  • 객체 사이의 관계를 one to many로 설정하는 어노테이션.
  • 객체사이의 관계를 설정하면 foreign key가 자동으로 설정된다.

@ManyToOne

  • 객체 사이의 관계를 many to one으로 설정하는 어노테이션.

board & comment entity 설계하기

  • 아래와 같은 쿼리문을 가진 board 테이블을 entity로 만들어보자!
create table board
(
    id      int auto_increment
        primary key,
    title   varchar(100)                          null comment '제목',
    content text                                  null comment '내용',
    created timestamp default current_timestamp() null,
    updated timestamp                             null on update current_timestamp()
)
    comment '게시판';
  • src 폴더 아래 entitiy 폴더를 생성하고 Board.ts 파일을 생성하자.

src/entity/Board.ts

import {Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn} from "typeorm";
 
@Entity()
export class Board {
  @PrimaryGeneratedColumn()
  id: number;
 
  @Column({length: 100})
  title: string;
 
  @Column("text")
  content: string;
 
  @CreateDateColumn()
  created: Date;
 
  @UpdateDateColumn()
  updated: Date;
}

  • 아래와 같은 쿼리문을 가진 comment 테이블도 entity로 만들어보자!
  • foreign key 부분은 아래에서 설명할 것이다!
create table comment
(
    id       int auto_increment
        primary key,
    content  text                                  null,
    created  timestamp default current_timestamp() null,
    updated  timestamp                             null on update current_timestamp(),
    board_id int                                   null,
    constraint comment_board_id_fk
        foreign key (board_id) references board (id)
)
    comment '댓글';
  • src폴더 아래 entity 폴더에 Comment.js 파일을 만들자.

src/entity/Comment.ts

import {Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn} from "typeorm";
 
@Entity()
export class Comment {
  @PrimaryGeneratedColumn()
  id: number;
 
  @Column("text")
  content: string;
 
  @CreateDateColumn()
  created: Date;
 
  @UpdateDateColumn()
  updated: Date;
}
  • 재시작 후 database 탭의 refesh 버튼을 누르면 테이블이 생성된다!

board & comment 관계 설정

  • 기존의 MariaDB 같은 관계형 DB에서 관계를 설정하기 위해 foreign key를 설정했지만 typeORM은 객체사이의 관계를 어노테이션으로 설정하면 foreign key가 자동으로 설정된다.

 

  • board 테이블은 여러개의 comment 테이블을 가지는 one to many 관계이므로 아래처럼 Board.ts 파일을 바꾸자!

src/entity/Board.ts

import {Column, CreateDateColumn, Entity, OneToMany, PrimaryGeneratedColumn, UpdateDateColumn} from "typeorm";
import {Comment} from './Comment';
 
@Entity()
export class Board {
  @PrimaryGeneratedColumn()
  id: number;
 
  @Column({length: 100})
  title: string;
 
  @Column("text")
  content: string;
 
  @CreateDateColumn()
  created: Date;
 
  @UpdateDateColumn()
  updated: Date;
 
  @OneToMany(type => Comment, comment => comment.board)
  comments: Comment[];
}
  • comment 테이블은 하나의 board 테이블을 가지는 many to one 관계이므로 아래처럼 Comment.ts 파일을 바꾸자.
  • 추가로 테이블 조인 없이 foreign key를 사용할 수 있도록 typeorm에서 제공해주는 방법을 사용해서 Column을 하나 추가하자

src/entity/Comment.ts

import {
    Column,
    CreateDateColumn,
    Entity,
    ManyToOne,
    PrimaryGeneratedColumn,
    UpdateDateColumn
} from "typeorm";
import {Board} from "./Board";

@Entity()
export class Comment {
    @PrimaryGeneratedColumn()
    id: number;

    @Column("text")
    content: string;

    @CreateDateColumn()
    created: Date;

    @UpdateDateColumn()
    updated: Date;

    @ManyToOne(type => Board, board => board.comments, {onDelete: 'CASCADE', onUpdate: "CASCADE"})
    board: Board;
    
    // join 없이 board의 id 사용 가능
    @Column()
    boardId: string
}
  • 서버를 재시작 후 database 탭에서 refresh한 후, comment 테이블을 우클릭 한 후 SQL scripts -> SQL generator를 클릭하면 하단의 DDL 문에 boardId 필드가 생성되어 있고, 이 필드에 foreign 키가 설정되어 있다!

+++ 문자열셋(이모지) 처리하기

  • MySql과 MariaDB에 이모지를 넣을 경우 오류가 발생한다!
  • 서버가 에러코드를 던지고  끝나는게 아니라 서버가 꺼지므로 만약 comment와 board 테이블에 이모지를 넣고 싶다면 꼭 설정을 해주자

 

  • 테이블 우클릭 → Jump To Query Console
  • 아래 명령어를 입력 후 전체 쿼리문을 드래그 후 왼쪽 상단의 실행 버튼 클릭
ALTER DATABASE duckDB
CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;

ALTER TABLE board
CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

ALTER TABLE comment
CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

+++ 참고사항

  • 위처럼 nodejs 프로젝트에서 엔티티를 설계하면 DataGrip으로 테이블을 넣지 않아도 프로젝트를 실행하면 자동으로 테이블이 생성된다!