2. Nest.js 광부왕 게임 서버 Mysql TypeOrm 설정 [게임 데이터]

2023. 2. 16. 22:10프로젝트/게임 서버 - Nest.js

1. Configuration 설정

https://crispypotato.tistory.com/194

 

Nest .env 파일 사용 방법

1. 설치 npm i --save @nestjs/config https://crispypotato.tistory.com/192 Nest 설치 방법 [ CLI ] 전역 설치 npm i -g @nestjs/cli 프로젝트 생성 nest new 생성 할 프로젝트 이름 생성 중에 패키지 관리툴을 선택하면 설치

crispypotato.tistory.com



2. 라이브러리 설치

typeorm, @nestjs/typeorm, mysql2 설치

npm install --save typeorm mysql2 @nestjs/typeorm

 

3. model 파일 생성

src폴더 안에 model 폴더를 만든 후 안에 model 파일 생성

model

users.model.ts

stages.model.ts

items.model.ts

gifts.model.ts

game-records.mode.ts

companies.model.ts

 

유저 테이블 users.model.ts

: 유저 아이디, 비밀번호와 같은 계정 정보

게임 기록 테이블 1:1 관계

보유 아이탬 테이블 1:1 관계

회사 테이블 1:1 관계

선물 테이블 N:1 관계

import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, IsNotEmpty, IsString } from 'class-validator';
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Users {
  @PrimaryGeneratedColumn('uuid')
  @IsString()
  @IsNotEmpty()
  userIndex: string;

  @ApiProperty({
    example: 'testID',
    description: 'id',
    required: true,
  })
  @Column({ type: 'varchar', length: 10, unique: true })
  @IsString()
  @IsNotEmpty()
  id: string;

  @ApiProperty({ example: 'pwd123', description: 'password', required: true })
  @Column({ type: 'varchar', length: 128 })
  @IsString()
  @IsNotEmpty()
  password: string;

  @Column({ type: 'varchar', length: 20 })
  @IsString()
  @IsNotEmpty()
  salt: string;

  @ApiProperty({
    example: 'testNickname',
    description: 'nickname',
    required: true,
  })
  @Column({ type: 'varchar', nullable: true, default: null })
  @IsString()
  nickname: string;

  @Column({ type: 'boolean', default: true })
  @IsBoolean()
  status: boolean;

  @Column({ type: 'boolean', default: true })
  @IsBoolean()
  accessLevel: boolean;
}

 

아이탬 테이블 items.model.ts

: 유저가 보유한 아이탬 정보

유저 테이블과 1:1 관계

CASCADE 설정

import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
  JoinColumn,
  OneToOne,
} from 'typeorm';
import { Users } from './users.model';

@Entity()
export class Items {
  @PrimaryGeneratedColumn('uuid')
  index: string;

  @OneToOne(() => Users, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'user' })
  user: string;

  @Column({ type: 'int', default: 1 })
  drill: number;

  @Column({ type: 'int', default: 1 })
  oxygenRespirator: number;

  @Column({ type: 'int', default: 1 })
  dynamite: number;

  @Column({ type: 'int', default: 1 })
  coworker: number;

  @Column({ type: 'int', default: 0 })
  gold: number;
}

 

게임 내역 테이블 game-records.mode.ts

: 유저가 진행한 게임 기록

유저 테이블과 1:1 관계

CASCADE 설정

import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
  JoinColumn,
  OneToOne,
} from 'typeorm';
import { Users } from './users.model';

@Entity()
export class GameRecords {
  @PrimaryGeneratedColumn('uuid')
  index: string;

  @OneToOne(() => Users, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'user' })
  user: string;

  @Column({ type: 'int', default: 1 })
  stage: number;

  @Column({ type: 'int', default: 1 })
  level: number;

  @Column({ type: 'int', default: 0 })
  exp: number;
}

 

회사 테이블 companies.model.ts

: 유저가 소속된 회사 정보

유저 테이블과 1:1 관계

CASCADE 설정

import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
  OneToOne,
  JoinColumn,
} from 'typeorm';
import { Users } from './users.model';

@Entity()
export class Companies {
  @PrimaryGeneratedColumn('uuid')
  index: string;

  @OneToOne(() => Users, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'user' })
  user: string;

  @Column({ type: 'varchar', length: 20 })
  companyName: string;

  // 5 > 4 > 3 > 2 > 1
  // 이사 > 상무 > 전무 > 부사장 > 사장
  @Column({ type: 'int', default: 0, width: 5 })
  position: number;
}

 

선물 테이블 gifts.model.ts

: 유저끼리 전달한 선물 정보

유저 테이블과 1:N 관계

import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
  JoinColumn,
  ManyToOne,
} from 'typeorm';
import { Users } from './users.model';

@Entity()
export class Gifts {
  @PrimaryGeneratedColumn('uuid')
  index: string;

  @ManyToOne(() => Users, (users) => users.userIndex)
  @JoinColumn({ name: 'sendUser' })
  sendUser: string;

  @Column({ type: 'varchar', length: 36 })
  receiveUser: string;

  @Column({ type: 'int', default: 0 })
  gold: number;

  @Column({ type: 'varchar', length: 50, nullable: true })
  message: string;

  @Column({ type: 'boolean', default: false })
  status: boolean;
}

 

스테이지 난이도 정보 테이블 stages.model.ts

: 스테이지 난이도 저장 테이블

다른 테이블과 연결된 관계가 없음

Static 데이터로 나누지 않는 이유는 관리자가 스테이지를 손 쉽게 늘릴수 있기 위함

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Stages {
  @PrimaryGeneratedColumn()
  stage: number;

  @Column({ type: 'int', default: 0 })
  coal: number;

  @Column({ type: 'int', default: 0 })
  bronze: number;

  @Column({ type: 'int', default: 0 })
  silver: number;

  @Column({ type: 'int', default: 0 })
  emerald: number;

  @Column({ type: 'int', default: 0 })
  amethyst: number;

  @Column({ type: 'int', default: 0 })
  diamond: number;

  @Column({ type: 'int', default: 0 })
  lithium: number;

  @Column({ type: 'int', default: 0 })
  useDynamite: number;
}

 

4. typeorm mysql 연결

app.module.ts 파일을 수정 한다.

* synchronize 가 true 일 경우 스키마가 수정되니 개발 시 필요 할 때만  true로 설정

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Companies } from './model/companies.model';
import { GameRecords } from './model/game-records.mode';
import { Gifts } from './model/gifts.model';
import { Items } from './model/items.model';
import { Stages } from './model/stages.model';
import { Users } from './model/users.model';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: process.env.MYSQL_HOST,
      port: Number(process.env.MYSQL_PORT),
      username: process.env.MYSQL_USERNAME,
      password: process.env.MYSQL_PASSWORD,
      database: process.env.MYSQL_DB,
      entities: [Companies, GameRecords, Gifts, Items, Stages, Users],
      synchronize: JSON.parse(process.env.MYSQL_SYNC),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

파일을 설정 해주고 서버를 시작하면 mysql에 자동으로 스키마 설정이 된다.

728x90
반응형