오늘의 목표
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;
}
};
}
연결하니 정상 작동되었다!