본문 바로가기
코딩과 알고리즘

node.js express | 템플릿쪽지함 #7. mysql2 프로미스

지난 스토리에서 다루었던 쪽지 템플릿에는 MYSQL 이라는 저장하는 부분을 비롯하여
클래스라는 부분까지 여러 요소가 추가되었는데요.
node.js의 프로미스라는 특징적 부분까지 다루어야 해서 예제 소스를 만들면서
점진적으로 소스를 완성하는 부분을 다뤄보도록 하겠습니다.

https://itadventure.tistory.com/443

 

node.js express | 템플릿 쪽지함#6. 쪽지 데이터베이스 저장

지난 스토리에서는 MYSQL 커뮤니티 서버를 서버에 설치하였지요. https://itadventure.tistory.com/442 node.js express | 템플릿 쪽지함#5. AWS 에 MYSQL 설치 이틀 가량 중 짜투리 시간을 투자해서 node.js 에..

itadventure.tistory.com


node.js 에서 쪽지를 저장하고 저장한 쪽지를 불러오는 등의 동작을 수행하기 위해서는
특별한 저장공간에 쪽지들을 담아두어야 하는데요.
보통 MYSQL 이라는 데이터베이스를 사용합니다.

node.js 에서는 MYSQL 데이터베이스를 사용하기 위한 모듈로
mysql 모듈과 mysql2 모듈이 있는데 보통 mysql 모듈보다는 사용이 용이한 mysql2 모듈을 사용합니다.

아래 명령행은 node.js 에서 mysql2 모듈을 사용하는 방법입니다.

< 터미널 창에서 mysql2 모듈 설치 >

npm install mysql2


< node.js 소스에서 mysql2 모듈 사용 선언 >

const mysql = require('mysql2/promise');


대략 아래와 같은 소스가 express 와 함께 mysql2 모듈을 사용하기 위한 기본 소스인데요.

const express=require('express');
const bodyParser = require('body-parser');
const ejs=require("ejs");
const app=express();
const mysql = require('mysql2/promise')

const db = mysql.createPool({
  host: 'localhost',
  port: 3306,
  user: 'cray',
  password: '4321',
  database: 'myroom'
})


본문 중에서 MYSQL 데이터베이스에 접속할 db 라는 오브젝트를 생성합니다.
db 오브젝트를 생성할 때는 MYSQL 에 접속할 정보를 기재해줍니다.
host 는 다른 서버에 접속하는 경우를 제외하고는 'localhost' 입니다.
port 역시 특별히 변경하지 않은 이상 기본값인 3306을 사용하고,
user와 password 는 mysql 에서 생성했던 계정을 사용하면 됩니다.
그리고 database 는 사용할 데이터베이스의 이름을 정해주면 되는 것이지요.

const db = mysql.createPool({
  host: 'localhost',
  port: 3306,
  user: '데이터베이스 접속 아이디',
  password: '데이터베이스 접속 패스워드',
  database: '기본으로 사용할 데이터베이스'
})


문제는 이런 식으로 매번 파일을 편집하게 되면 그 때마다 데이터베이스 접속 아이디와 패스워드가 화면에 보여 집니다.
나 혼자 있는 장소에서 컴퓨터를 사용한다면야 상관없겠지만,
누군가 자리 옆을 지나가다 슬쩍 화면을 보기라도 한다면...?
아이쿠! 패스워드가 유출될 게 아닙니까?

그렇기 때문에 이런 민감한 정보는 별도의 파일로 빼두어 모듈화를 시켜두는게 좋습니다.
그래서 그 파일은 좀처럼 열어보지 않는 것이지요.

아래 소스는 db 접속 부분을 별도의 모듈로 뺀 것인데요.

< db.js 파일 >

const mysql = require('mysql2/promise')

const db = mysql.createPool({
  host: 'localhost',
  port: 3306,
  user: 'cray',
  password: '4321',
  database: 'myroom'
})

module.exports = db


mysql 모듈로 db 오브젝트를 생성한 다음에,
생성한 모듈을 module.exports = db 명령으로 밖에서 사용 가능하게 공개하게 되어 있습니다.

이렇게 db.js 에서 공개된 모듈은 다른 소스에서 아래와 같이 사용할 수 있는 것이지요.
그러면 똑같이 db 오브젝트를 사용할 수 있습니다.

const db = require('./db');


그래서 결국 db.js 를 별도의 파일로 분리한 경우 express 모듈와 함께 사용할 수 있는 보편적인 소스는 아래와 같습니다.

const express=require('express');
const bodyParser = require('body-parser');
const ejs=require("ejs");
const app=express();
const db = require('./db');


이제 쪽지를 한번 불러와보도록 하겠습니다.
쪽지를 불러오기 위해서는 SQL 쿼리(query) 문을 사용해야 하는데요.
보통 아래와 같이 사용합니다.

db.query(
  "SELECT x, y, r, memo FROM memolist"
);


여기서 "SELECT x, y, r, memo FROM memolist"라는 부분은
memolist 라는 테이블(표)로부터 (FROM memolist)
x, y, r, memo 라는 항목들을 선택하라는 (SELECT)
SQL(Structured Query Language) 문입니다.


이렇게 선택하는 동작을 Mysql 에서는 SELECT 한다고 표현하는데요.
이렇게 SELECT 한 결과를 node.js  에서 사용할 수가 있습니다.
그러기 위해서는 node.js 만의 독특한 방식을 사용해야 합니다.

일반적으로 php 나 asp, asp.net 경우 아와 같은 SQL 문을 실행하면,
해당 SQL문의 동작이 끝날때까지 기다려 준 다음에 그 다음 문장이 실행되는데요.

< php >

$result = $mysqli->query("SELECT * from memolist");

 

< ASP >

Set result = dbConn.Execute("SELECT * FROM memolist")

 

< ASP.NET >

SqlCommand result = new SqlCommand("SELECT * FROM memolist", conn);

result 변수에 처리할 수 있는 권한이 넘어오기 때문에,
반복문으로 자료를 꺼내는 것이 일반적인데요.

node.js는 다릅니다.

한번 소스를 아래와 같이 구성하고, 실행해 보세요. 파일명은 ex1.js 로 정해 볼까요?

node ex1.js
const express=require('express');
const bodyParser = require('body-parser');
const ejs=require("ejs");
const app=express();
const db = require('./db');

const data = db.query(
  "SELECT x, y, r, memo FROM memolist"
);

console.log(data);


그 결과는 아래와 같습니다.

Promise { <pending> } ?
이것은 무슨 의미일까요?

Promise 는 영어단어로는 '약속하다'란 의미이고,
pending 이란 영어단어로 어떤 일이 일어날때까지 기다리는 중이란 뜻이 있습니다. until 과 비슷하지요.

여기서는 실행한 SQL 문이 실행이 끝나면 그 결과를 반환해줄텐데요.
그 결과를 기다리고 있다는 약속덩어리를 의미합니다.

그래서 보통은 이렇게 정의된 약속의 결과물을 처리하기 위해 아래와 같은 방식이 사용됩니다.
여기서  result 는 [0]번과 [1]번, 2개의 배열 요소를 파라미터로 전달받는데요,
배열요소 [0]에 실제적인 SELECT 한 결과물을 받아옵니다.

data.then((result) => {
  console.log(result[0]);
});


역시 여기서도 착오 없으실 것은 node.js 는 이 부분의 실행이 끝나기까지 기다려주지 않는다는 것입니다.

소스가 아래와 같이 구성된 경우,  [ A 부분 ]이 실행이 끝난 다음, [ B  부분 ]이 실행되는 것이 아니라,
[ B 부분 ]이 먼저 실행이 되고 [ A 부분 ]이 실행이 됩니다.

const data = db.query(
  "SELECT x, y, r, memo FROM memolist"
);

data.then((result) => {
  [ A 부분 ]
});

[ B 부분 ]


왜냐하면 SQL문장을 실행하는 결과가 도착하는 시간을 기다리는 것이 비효율적이라고 판단,
node.js 에서는 다음문장을 바로 실행하도록 설계되었기 때문입니다.

SQL문의 실행결과가 반환되는 순간 A 부분이 실행이 되는데요.
바로 이 원리가 node.js가 다른 언어보다 탁월하게 빠른 작동을 가능하게 하는 부분입니다.

한번 아래와 같이 소스를 구성해 볼까요? 소스명은 ex2.js 입니다.

const express=require('express');
const bodyParser = require('body-parser');
const ejs=require("ejs");
const app=express();
const db = require('./db');

const data = db.query(
  "SELECT x, y, r, memo FROM memolist"
);

data.then((result) => {
  console.log(result[0]);
});

console.log("짠!");


위 소스를 실행하면 과연 그 결과는 어떻게 될까요?
데이터가 들어있는 result[0] 이 먼저 콘솔창에 출력될 것인지,
아니면 "짠!"이라는 문구가 먼저 콘솔창에 실행이 될까요?

node 서버를 중지하고 다시 실행해보면

node ex2.js


실행결과는 아래와 같습니다.
"짠 !"이 먼저 출력되었지요.


이와 같이 node.js 는 SQL문을 쿼리하는 약간 동작이 느린 기능에 대해,
프로미스라는 기법을 사용합니다.
그래서 SQL문을 실행하는 동안 다른 동작을 병행처리할 수 있기 때문에
이를 이용하면 매우 빠른 작동 속도를 보장할 수 있습니다.

위의 소스는 더욱 간추릴 수가 있는데요. 2개의 동작을 하나로 합칠수 있습니다.
아래와 같이 말입니다. 이렇게 하면 굳이 data 라는 변수로 결과를 받아오는 과정도 필요도 없지요.

db.query(
  "SELECT x, y, r, memo FROM memolist"
).then((result) => {
  console.log(result[0]);
});


결과 소스는 아래와 같습니다.  ex3.js  로 저장하시고, node 서버로 실행해 보세요.

const express=require('express');
const bodyParser = require('body-parser');
const ejs=require("ejs");
const app=express();
const db = require('./db');

db.query(
  "SELECT x, y, r, memo FROM memolist"
).then((result) => {
  console.log(result[0]);
});

console.log("짠!");
node ex3.js

결과화면은 동일합니다.

node.js 에서는 이와 같이 SQL문을 사용해 데이터를 받아올 수 있는데요.
빠른 속도를 보장하는 대신 순서대로의 처리가 불가하기 때문에
A작업이 끝나고 B작업이 실행되게 하려면 뭔가 특별한 처리가 필요합니다.

해당 부분은 다음 스토리에서 이어서 살펴보도록 하겠습니다.

오늘도 여기까지 읽어주셔서 감사합니다 :)


하나님의 말씀을 마음에 담아두면 내 영혼의 먹을 양식이 됩니다.

서로 인자하게 하며 불쌍히 여기며 서로 용서하기를 하나님이 그리스도 안에서 너희를 용서하심과 같이 하라
- 에베소서 4장 32절 말씀 -


다음 스토리 : #8 기다려! await!

https://itadventure.tistory.com/445

 

node.js express | #8. 기다려! await!

지난 스토리에서는 mysql2 모듈을 사용할 때 프로미스에 대해서 알아보았는데요. https://itadventure.tistory.com/444 node.js express | #7. mysql2 프로미스 지난 스토리에서 다루었던 쪽지 템플릿에는 MYSQL..

itadventure.tistory.com