[Node.js] MySQL로 기능 구현 (Create, Read)

2023. 3. 27. 21:29공부 중/Node.js


 

 

Node.js - MySQL - 생활코딩

수업소개 이 수업은 Node.js와 MySQL을 이용해서 웹애플리케이션을 만드는 방법에 대한 수업입니다.  수업대상 예를들어 1억 개의 페이지로 이루어진 웹사이트에서 필요한 정보가 파일에 하나하나

opentutorials.org

 

생활코딩 Node.js - MySQL 강의를 듣고서 작성한 글입니다. 그냥 그렇다고요.

 


1. 상세 보기 구현

 

MySQL에서 DB의 정보를 가져와서 상세 보기 페이지를 만들고 클라이언트에게 전송하기.

if (pathname === "/") {
    if (queryData.id === undefined) {
    ...
    } else {
          db.query(`SELECT * FROM topic WHERE id=?`, [queryData.id], function(error, topic){
          if(error){
            throw error;
          }
        const title = topic[0].title;
        const description = topic[0].description;
        const filteredId = path.parse(queryData.id).base;
        let control = `
          <input type="button" value="create" onclick="redirect(this, '${filteredId}')"/>
          <input type="button" value="update" onclick="redirect(this, '${filteredId}')"/>
          <form id="frm" action="delete_process" method="post" style="display:inline">
            <input type="hidden" name="id" value="${filteredId}">
            <input type="button" value="delete" 
            onclick="if(confirm('really delete?')==true){document.getElementById('frm').submit();}">
          </form>
        `;
        readAndRes(dataDir, title, description, control);
      });
    }
  } else if (pathname === "/create") {
  • db.query(SELECT * FROM topic WHERE id=?, [queryData.id], function(error, topic){ ... }
    : 쿼리문으로 url을 통해서 전달받은 query string의 id 값을 사용해서 DB에서 원하는 튜블을 획득한다.
  • const title = topic[0].title; const description = topic[0].description;
    : 전달받은 topic에서 title, description을 완성하기 위한 정보를 획득한다.

 


2. Create 구현

 

const qs = require("querystring");

...

} else if (pathname === "/create") {
    let title = "create";
    let description = `
        <form action="/create_process" method="post">
            <p><input type="text" name="title" placeholder="title"></p>
            <p>
                <textarea name="description" placeholder="description"></textarea>
            </p>
            <p>
                <input type="submit">
            </p>
        </form>
      `;
    let control = ``;
    readAndRes(dataDir, title, description, control);
  } else if (pathname === "/create_process") {
    let body = "";
    request.on("data", function (data) {
      body += data;
    });
    request.on("end", function () {
      let post = qs.parse(body);
      let title = post.title;
      let description = post.description;
      let filteredTitle = path.parse(title).base;
      let sanitizedTitle = sanitizeHtml(filteredTitle);
      let sanitizedDesc = sanitizeHtml(description);
      fs.writeFile(
        `${dataDir}/${sanitizedTitle}`,
        sanitizedDesc,
        "utf8",
        function (err) {
          response.writeHead(302, {
            Location: encodeURI(`/?id=${sanitizedTitle}`),
          });
          response.end();
        }
      );
    });
}

 


가. INSERT

request.on("end", function () {
      let post = qs.parse(body);
      let title = post.title;
      let description = post.description;
      let filteredTitle = path.parse(title).base;
      let sanitizedTitle = sanitizeHtml(filteredTitle);
      let sanitizedDesc = sanitizeHtml(description);
      db.query(`INSERT INTO topic (title, description, created, author_id) 
        VALUES (?, ?, NOW(), ?)`,[sanitizedTitle, sanitizedDesc, 1],
        function(error, result){
          if(error){
            throw error;
          }
        }
        ...
      );
});

기존의 코드에서 writeFile(...)INSERT 쿼리로 수정한다.

 

let title = post.title;
let description = post.description;
let filteredTitle = path.parse(title).base;
let sanitizedTitle = sanitizeHtml(filteredTitle);
let sanitizedDesc = sanitizeHtml(description);

 

보안을 위해서 작성했던 코드다.

 

여전히 XSS에 대처하기 위해서 sanitized-html은 필요하다.

 

하지만 더 이상 파일시스템을 사용하지 않기 때문에 title에 주소값이 들어와도 상관없다.

 

고로 filteredTitle은 필요 없다.

 

let title = post.title;
let description = post.description;
let sanitizedTitle = sanitizeHtml(title);
let sanitizedDesc = sanitizeHtml(description);

 


나. 리다이렉션

 

db.query(`INSERT INTO topic (title, description, created, author_id) 
    VALUES (?, ?, NOW(), ?)`,[sanitizedTitle, sanitizedDesc, 1],
    function(error, result){
        if(error){
            throw error;
        }
        response.writeHead(302, {
            Location: encodeURI(`/?id=${??????}`), //새로 생성한 튜플의 id값이 필요
        });
        response.end();
    }
);

INSERT가 마무리된 후에 리다이렉션하기 위해서는 새로 삽입한 튜플의 id가 필요하다.

 

  • INSERT INTO topic (title, description, created, author_id) VALUES(?, ?, NOW(), ?),`

 

하지만 우리는 다른 것은 다 알아도 id값은 모른다.

 

다시 SELECT 쿼리를 사용할 수도 있지만 다른 방법이 있다.

 

 

Get inserted id (node.js + mysql)

I try to get id of user (auto increment id field) when insert data to user table. Here is ,my code: let sql = "INSERT into users(name, date, photo) VALUES ('"+name+"', '"+date+"', '"+photo+"')"...

stackoverflow.com

 

result.insertId를 사용하면 INSERT를 통해서 새로 생성한 튜플의 id값을 별도의 작업 없이 바로 알아낼 수 있다.

 

db.query(`INSERT INTO topic (title, description, created, author_id) 
        VALUES (?, ?, NOW(), ?)`,[sanitizedTitle, sanitizedDesc, 1],
        function(error, result){
          if(error){
            throw error;
          }
          response.writeHead(302, {
            Location: encodeURI(`/?id=${result.insertId}`),
          });
          response.end();
        }
      );
    });