node.js MySQL #2

학미새🐥·2022년 2월 19일
0
post-custom-banner

MySQL로 상세보기 구현

기존의 상세보기 구현 코드 (파일을 통해 글을 관리하는 방식)

  1. 글 목록 가져오기
    기존 : fs.readdir
    db.query(SELECT * FROM topic, function(error,topics){}

홈화면에서 글목록을 가져오는 코드를 그대로 사용하면 된다.

db.query(`SELECT * FROM topic`, function(error,topics){
  var title = 'Welcome';
  var description = 'Hello, Node.js';
  var list = template.list(topics);
  var html = template.HTML(title, list,
                           `<h2>${title}</h2>${description}`,
                           `<a href="/create">create</a>`
                          );
  response.writeHead(200);
  response.end(html);
});
  1. queryString에 따라 다른 페이지 구현
    id값을 가져오기 위한 SQL 쿼리 : SELECT * FROM topic WHERE id=3;
    이를 node.js를 통해 실행하기 위해
    db.query(SELECT * FROM topic WHERE id=?,[queryData.id], function(error2, topic){}
  • queryData.id : URL의 queryString의 id값을 가져와서 쿼리문에 사용하기

상세보기 페이지의 구현 순서는 다음과 같다
1. 글 목록을 가져온 뒤,
2. id값을 통해 해당하는 글의 정보를 가져오고
3. 상세보기 화면을 구현하기
여기서 글 데이터를 가져오지 못할 경우에 error를 처리해주기 위해

if(error){
  throw error;
}

에러를 탐지하자마자 즉시 애플리케이션을 종료시킨다.

이렇게 순서와 에러처리를 구현한 코드는 다음과 같다

db.query(`SELECT * FROM topic`, function(error,topics){
  if(error){
    throw error;
  }
  db.query(`SELECT * FROM topic WHERE id=${queryData.id}`, function(error2, topic){
    if(error2){
      throw error2;
    }
    var title = topic[0].title;
    var description = topic[0].description;
    var list = template.list(topics);
    var html = template.HTML(title, list,
                             `<h2>${title}</h2>${description}`,
                             ` <a href="/create">create</a>
<a href="/update?id=${queryData.id}">update</a>
<form action="delete_process" method="post">
<input type="hidden" name="id" value="${queryData.id}">
<input type="submit" value="delete">
</form>`
                            );
    response.writeHead(200);
    response.end(html);
  })
});
  • 이때 주의해야할 사항 : topic에 담기는 결과는 배열의 형태이기 때문에
    topic[0] 식으로 인덱스를 지정해줌을 통해 배열의 요소인 객체에 접근해야 한다.

db.query(`SELECT * FROM topic WHERE id=${queryData.id}`, function(~){});

데이터베이스가 가지는 코드 특성에 따라 사용자의 입력으로 인해 공격받을 수 있다.
따라서 id값이 들어가야할 자리에 ?를 적어주고, ?에 어떤 값이 들어가야할 지는 그 다음의 인자에 작성하여 분리시켜준다

db.query(SELECT * FROM topic WHERE id=?`,[queryData.id],function(~){});
  • 두번째 인자에 있는 값이 첫번째 쿼리문의 ?자리를 치환하는 과정에서 공격성을 검사하고 세탁하기 때문에!

상세화면에 구현될 글 생성, 글 수정, 글 삭제 링크도 마저 구현한다.

<a href="/create">create</a>
<a href="/update?id=${queryData.id}">update</a>
<form action="delete_process" method="post">
  <input type="hidden" name="id" value="${queryData.id}">
  <input type="submit" value="delete">
</form>

글 생성 기능 구현 (사용자가 온라인에서 데이터 추가하기)

  • 기존 글 생성 UI
fs.readdir('./data', function(error, filelist){
  var title = 'WEB - create';
  var list = template.list(filelist);
  var html = template.HTML(title, list, `
<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>
`, '');
  response.writeHead(200);
  response.end(html);
});
  • MySQL을 사용한 글 생성 UI
db.query(`SELECT * FROM topic`, function(error,topics){
  var title = 'Create';
  var list = template.list(topics);
  var html = template.HTML(title, list,
     `<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>`,
      `<a href="/create">create</a>`
  );
  response.writeHead(200);
  response.end(html);
});

create_process 웹서버에서
submit 버튼을 클릭 했을 때 실행돼야하는 쿼리문
INSERT INTO topic (title, description, created, author_id) VALUES('제목', '본문', NOW(), 1);

  • 이 때, 앞서 말했던 바와 같이 사용자의 입력을 받는 내용에 대해서는 공격성을 조심해야 한다. 따라서 현재시간을 불러오는 함수인 NOW() 를 제외한 세 인자 (제목, 본문, 작성자id) 모두 query엔 ?로 작성한 뒤, 별도의 인자에 배열형태로 분리시켜야 한다.
INSERT INTO topic (title, description, created, author_id) VALUES(?, ?, NOW(), ?)`,[post.title, post.description, 1]
  • callback에서는 1. 에러처리 2. 생성한 글 화면으로 Redirection 하면 된다.
function(error, result){
  if(error){
    throw error;
  }
  response.writeHead(302, {Location: `/?id=${result.insertId}`});
  response.end();
}

여기서
방금 삽입한 데이터의 id값을 불러와야 한다.

result.insertId

callback function의 result인자에 담기는 결과값의 insertId property에 접근하면 된다.

profile
뭐든 다해보려는 공대생입니다
post-custom-banner

0개의 댓글