TIL : sequelize없이 query문으로 생성한MySQL 테이블과 연결하기

ESH'S VELOG·2023년 7월 28일
0

오늘의 목표
query문으로 생성한 MySQL DB를 서버와 연결시켜주기

우선 app.js

import mysql from 'mysql2/promise';

export const databaseConnection = {
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
};
class ExpressApp {
	dbConnection;
    runServer = async () => {
    try {
      this.setAppsettings();
      await this.runDatabase();
      this.setAppRouter();
      return this.serverListen();
    } catch (e) {
      return this.serverErrorHandler(e);
    }
    }
    runDatabase = async () => {
    try {
      this.dbConnection = await mysql.createConnection(databaseConnection);
      console.log(`${databaseConnection.database}로 연결되었습니다.`);
    } catch (e) {
      console.error('Error: ', e);
    }
  };
}

export default ExpressApp;
export const expressApp = new ExpressApp();
export const dbConnection = expressApp.dbConnection;
expressApp.runServer();
expressApp.setAppRouter();

그리고 app.js를 실행한 뒤 터미널에서 연결이 되었다는 문구가 떴다.

kiosk로 연결되었습니다.
Server is Running on http://localhost:3000

그 다음은 기능을 실행해볼 차례이다
우선 POST를 이용하여 실제 값을 DB에 저장해 볼 예정이다.

로직 순서
router > itemController > itemService > itemRepository

import { dbConnection } from '../app.js';

class ItemRepository {
  addItem = async (name, price, type, amount) => {
    try {
      console.log('레파지토리', dbConnection);
      const sql =
        'INSERT INTO item (name, price, type, amount) VALUES (?, ?, ?, ?)';
      const [result] = await dbConnection.query(sql, [
        [name, price, type, amount],
      ]);
      console.log(result);
      return result.insertId;
    } catch (error) {
      throw error;
    }
  };
}

export default ItemRepository;

실행 결과 에러가 떴다.
이유는 dbConnection.query의 프로퍼티를 읽어낼 수가 없다는 것이었다.

=======문제 해결 과정======
우선 dbConnection에서 어떻게 가져오는지 확인해보았다.
1) repository에서 dbConnection console.log 결과 = undefined
2) app.js에서 dbConnection에서 console.log결과 = undefined
3) app.js에서 console.log(this.dbConnection)결과 PromiseConnection 객체 반환

즉,
1) mysql로 createConnection메서드를 사용 시 dbConnection은 데이터베이스와 연결하고 정상작동하고 있으며,
2) export과정에서 잘못된 경로로 보내지는 것이 아닌가 추측이 된다.

======== 문제 해결 ============
방법은 class를 통해 인스턴스를 생성하는 방법에 있었다.
위와 같이 작성하면 로직이 다음과 같다.
ExpressApp이라는 클래스를 생성 => ExpressApp클래스만 내보낸다 => expressApp이라는 인스턴스도 내보낸다 => dbConnection도 내보낸다. => expressApp 인스턴스의 runServer를 실행 => expressApp 인스턴스의 setAppRouter()를 실행

1) 틀린 부분: export default {내보내는 대상}
이 문장을 쓰면 내보내는 대상밖에 export할 것이 없다 라는 뜻이다.
2) ExpressApp클래스, 인스턴스 등 다 내보내놓고 메소드들을 실행하니 export한 대상들은 모두 initialization(초기화)된 상태로 내보내지니 당연히 connection도 실행되지 않은 상태로 나가서 repository에서는 당연히 undefined로 받는 것이다.

즉 로직을 이렇게 바꾸면 된다.
인스턴스 생성 => 인스턴스에서 서버와 DB를 연결하는 메서드 실행 => 실행된 인스턴스만 export

const expressApp = new ExpressApp();
expressApp.runServer();
expressApp.setAppRouter();
export default expressApp;

itemRepository에서는 다음과 같이 바꾸면 된다.
1) export된 인스턴스를 import
2) 인스턴스의 dbConnection.query를 실행

import expressApp from '../app.js';
class ItemRepository {
  addItem = async (name, price, type, amount) => {
    try {
      const sql = 'INSERT INTO item (name, price, type, amount) VALUES (?)';
      const [result] = await expressApp.dbConnection.query(sql, [
        [name, price, type, amount],
      ]);
      return result.insertId;
    } catch (error) {
      throw error;
    }
  };
}

연결하니 정상 작동되었다!

profile
Backend Developer - Typescript, Javascript 를 공부합니다.

0개의 댓글