백엔드/node.js

node.js에서 mysql 연결

STUFIT 2022. 5. 28. 20:51
반응형

node.js 에서는 mongodb, mysql, postgresql etc... 를 연결하여 사용가능한데, 이번에는 mysql을 연결하여 node.js에서 mysql을 이용하고자 한다.

mysql, mysql2 2가지 패키지가 제공되는데 mysql2가 좀 더 많은 기능을 제공하는 것으로 알고 있기 때문에 mysql2를 설치하여 db 연결을 진행할 예정이다.

1. install

npm install --save mysql2

2. database.js 파일 생성 및 코드 추가

db를 연결하기 위해 data라는 폴더에 database.js 를 추가하여 아래의 코드를 적어주어 db연결준비를 한다.

보통 mysql 에서는 createConnection 함수를 사용하는데, 이는 로컬개발에서는 상관없지만 추후 많은 요청을 서버에 보낼때에는

효율적이지 않으므로 createPool로 연결한다.

// db 비동기 처리를 위해 promise를 붙여준다.
// db 산출시 모든 쿼리에서 비동기 promise 산출하는지 확인 가능하다.
const mysql = require('mysql2/promise');

// db 연결을 위한 createConnection 함수를 제공하지만, 해당 부분에서는 연결 풀을 제공하는 createPool 함수를 이용함.
// createPool은 로컬 개발 및 간단한 웹사이트에서는 유용하지 않지만, 동시에 많은 요청을 처리해야되는 상황에서는 개별마다 connection을 만드는 것보다 훨씬 유용하다.
// createPool은 자동으로 사용 및 관리되기 때문이다.
const pool =  mysql.createPool({
    host : '127.0.0.1',
    database : 'udemy',
    user : 'root',
    password : 'root',
});

module.exports = pool;

* 위에서 host 지정 시, host : 'localhost' 로 지정하니 다음과 같은 에러가 발생하여 127.0.0.1 로 변경하였더니 정상적으로 작동하였다.

원인은 추후 발견 시, 작성예정이다.

/Users/stufit/Documents/GitHub/100days_bootcamp_nodejs/section24_nodejs&mysql/node_modules/mysql2/promise.js:341
    const localErr = new Error();
                     ^

Error: connect ECONNREFUSED ::1:3306
    at PromisePool.query (/Users/stufit/Documents/GitHub/100days_bootcamp_nodejs/section24_nodejs&mysql/node_modules/mysql2/promise.js:341:22)
    at /Users/stufit/Documents/GitHub/100days_bootcamp_nodejs/section24_nodejs&mysql/routes/blog.js:18:32
    at Layer.handle [as handle_request] (/Users/stufit/Documents/GitHub/100days_bootcamp_nodejs/section24_nodejs&mysql/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/stufit/Documents/GitHub/100days_bootcamp_nodejs/section24_nodejs&mysql/node_modules/express/lib/router/route.js:144:13)
    at Route.dispatch (/Users/stufit/Documents/GitHub/100days_bootcamp_nodejs/section24_nodejs&mysql/node_modules/express/lib/router/route.js:114:3)
    at Layer.handle [as handle_request] (/Users/stufit/Documents/GitHub/100days_bootcamp_nodejs/section24_nodejs&mysql/node_modules/express/lib/router/layer.js:95:5)
    at /Users/stufit/Documents/GitHub/100days_bootcamp_nodejs/section24_nodejs&mysql/node_modules/express/lib/router/index.js:284:15
    at Function.process_params (/Users/stufit/Documents/GitHub/100days_bootcamp_nodejs/section24_nodejs&mysql/node_modules/express/lib/router/index.js:346:12)
    at next (/Users/stufit/Documents/GitHub/100days_bootcamp_nodejs/section24_nodejs&mysql/node_modules/express/lib/router/index.js:280:10)
    at Function.handle (/Users/stufit/Documents/GitHub/100days_bootcamp_nodejs/section24_nodejs&mysql/node_modules/express/lib/router/index.js:175:3) {
  code: 'ECONNREFUSED',
  errno: -61,
  sql: undefined,
  sqlState: undefined,
  sqlMessage: undefined
}

3. blog.js에 라우터 추가작업

const express = require('express');

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

const router = express.Router();

router.get('/', (req,res)=>{
    res.redirect('/posts');
});

router.get('/posts', (req,res)=>{
    res.render('posts-list');
});

router.get('/new-post',async(req,res)=>{
    // 쿼리를 실행하고, 해당 쿼리를 db로 보내는 내장 메소드이다.
    // db쿼리를 비동기처리함, 배열의 비구조화로 진행
    const [authors] = await db.query('SELECT * FROM authors'); 
    res.render('create-post',{authors:authors}); // key값은 templates에 노출될 값이며, value값은 실제 authors의 데이터값(비구조화한 authors)을 뜻한다.
});



module.exports = router;

4. create-post.ejs 파일 작업

select author 부분에 blog에서 전달받은 authors를 for 문을 통해 풀어주어 value값을 얻는다.

<!DOCTYPE html>
<html lang="en">

<head>
  <%- include('includes/head', { title: 'Add new post' }) %>
  <link rel="stylesheet" href="/styles/forms.css">
</head>

<body>
  <%- include('includes/header') %>
  <main>
    <h1>Add a new post</h1>
    <form action="..." method="...">
      <div class="form-control">
        <label for="title">Title</label>
        <input type="text" id="title" name="title" required>
      </div>
      <div class="form-control">
        <label for="summary">Summary</label>
        <input type="text" id="summary" name="summary" required maxlength="255">
      </div>
      <div class="form-control">
        <label for="content">Post Content</label>
        <textarea id="content" name="content" required rows="5"></textarea>
      </div>
      <div class="form-control">
        <label for="author">Select Author</label>
        <select id="author" name="author">
          <% for (const author of authors) { %> 
              <option value="<%= author.id %>"><%= author.name %></option>
            <% } %> 
        </select>
      </div>
      <button class="btn">Add Post</button>
    </form>
  </main>
</body>

</html>

5. 결과값

udemy db 의 author 테이블에 있는 값이 잘 전달되어 select Author에서 보여지는 모습

반응형