실습 - MySQL + Node.js CRUD

nayonsoso·2021년 4월 26일
0

기본 설정

// express 모듈 require + 객체화
var express = require('express');
var app = express();

// post data 받기 위해 bodyParser 미들웨어 require
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));

// 템플릿엔진 설정 (view engine : 엔진 종류 설정, views : 폴더 설정)
app.set('view engine','pug');
app.set('views', './views');
app.locals.pretty = true;

// mysql 연결
var mysql = require('mysql');
var conn = mysql.createConnection({
  host : 'localhost',
  user : 'root',
  password : '129329aa',
  database : 'TWICE'
});
conn.connect();

// 포트와 연결
app.listen(3000,function(){
	console.log('트와이스 플레이리스트에 오신걸 환영합니다!');
});

메인페이지 + 글 상세보기

app.get(['/playlist','/playlist/:id'], function(req,res){ // 메인 + 세부 페이지
  // get [] 으로 라우팅 -> 다수의 url 받을 수 있음

  var sql = 'SELECT ID, s_name FROM twice_song';
  conn.query(sql,function(err,songs_app,fields){ 
		// conn.query()는 인자로 받는 sql문의 해당 행을 콜백함수의 매개변수로 넘김
		// songs_app는 데이터베이스의 모든 ID, s_name

		// /playlist/:id의 ':id' 는 시멘틱 url의 전달방법
		// 시멘틱 url을 받으려면 params 객체 사용
    var id = req.params.id; // url로 전달된 id 즉, song.ID

    if (id){ // url에 id가 있는 경우 - 하부 페이지 렌더, 단일 row 전달 o
      // 라우팅 안에 또 다시 라우팅 -> if 문으로 ;
      var sql='SELECT * FROM twice_song where ID = ?'
      conn.query(sql, [id], function(err,song_app,fields){
        // ? 사용 -> .query 두번째 인자로 [] 전달
        // song_app은 id 가 일치하는 하나의 행
        if(err){ // 에러 o
          console.log(err);
          res.status(500).send('Internal Server Error');
          // status가 뭔진 모르겠으나 send는 express에서 html을 웹에 출력해준다.
        } else { // 에러 x
          res.render('view',{songs_pug: songs_app, song_pug:song_app[0]})
          // song_app은 배열로 전달되므로 song_app[0] == 헤당 노래의 row
        }
      });
    }else{  // url에 id가 없는 경우 - 메인 페이지 렌더, 단일 row 전달 x
    res.render('view', {songs_pug: songs_app});
    }
  })
});

▽ views/view.pug

doctype html
html
  head
    meta(charset='utf-8')
  body
    h1
      a(href='/playlist') TWICE
    ul
      each asong in songs_pug
        li
          a(href='/playlist/'+asong.ID)= asong.s_name
    article
      if song_pug
        h2= song_pug.s_name
        = song_pug.s_desc
      else
        h2 Welcome
        | Welcom to twice's music list!
    div
      a(href='/playlist/add') add

페이지 추가

// get add 페이지 (작성)
app.get('/playlist/add',function(req,res){ 
  // 어째서인지 /:id 보다 먼저 읽어야 한다.
  var sql = 'SELECT ID, s_name FROM twice_song';
  conn.query(sql,function(err,songs_app,fields){
    if(err){ // 에러 o
      console.log(err);
      res.status(500).send('Internal Server Error');
    } else { // 에러 x - add.pug를 렌더해오는데, 변수로 songs_app전달
      res.render('add',{songs_pug: songs_app});
    }
  })
});

// post add 페이지 (데이터 전달받고 리다이렉트, 사용자에겐 보이지 않는 페이지)
app.post('/playlist/add', function(req,res){ 
  var title = req.body.title; // body객체 - post 방식으로 전송한 데이터 받기
  var description = req.body.description;
  var sql = 'INSERT INTO twice_song (s_name,s_desc) VALUES (?,?)'
  conn.query(sql,[title, description], function(err, rows, fields){
		// ? 사용 -> .query 두번째 인자로 [] 전달
    if(err){
      console.log(err);
      res.status(500).send('Internal Server Error');
    } else {
      res.redirect('/playlist/'+rows.insertId);
      // redirect는 해당 주소로 리다이렉트 해주는 메서드
      // insert문에 해당하는 rows는 ID가 없으므로 ID 대신 insertId 사용
    }
  })
})

▽ views/add.pug

doctype html
html
  head
    meta(charset='utf-8')
  body
    h1
      a(href='/playlist') TWICE
    ul
      each asong in songs_pug
        li
          a(href='/playlist/'+asong.ID)= asong.s_name
    article
      form(action='/playlist/add' method='post')
        p
          input(type='text' name='title' placeholder='title')
        p
          textarea(name='description' placeholder='description')
        p
          input(type='submit')

페이지 수정

// get edit 페이지 (작성)
app.get('/playlist/:id/edit', function(req,res){
  var sql = 'SELECT * FROM twice_song';
  conn.query(sql,function(err,songs_app,fields){
    var id = req.params.id;
    if (id){ // id 있을 때
      var sql='SELECT * FROM twice_song where ID = ?'
      conn.query(sql, [id], function(err,song_app,fields){
        if(err){ // 에러 o
          console.log(err);
          res.status(500).send('Internal Server Error');
        } else { // 에러 x
          res.render('edit',{songs_pug: songs_app, song_pug:song_app[0]})
        }
      })
    } else{ // id가 없을 때
      console.log(err);
      res.status(500).send('Internal Server Error');
    }
  })
});
// post edit 페이지 (데이터 전달받고 리다이렉트, 사용자에겐 보이지 않는 페이지)
app.post('/playlist/:id/edit', function(req,res){
  var sql = 'UPDATE twice_song SET s_name=?, s_desc=? WHERE ID=?';
  var title = req.body.title; // body객체:post 방식으로 전송한 데이터 받기
  var description = req.body.description;
  var id = req.params.id // ID는 form으로 전달받지 못했지만 시멘틱url로 받아올 수 있음
  conn.query(sql, [title, description, id], function(err,song_app,fields){
    if(err){ // 에러 o
      console.log(err);
      res.status(500).send('Internal Server Error');
    } else { // 에러 x
      res.redirect('/playlist/'+id); // 왜인지 '/' 빠뜨리면 안됨
    }
  })
})

▽ views/edit.pug

doctype html
html
  head
    meta(charset='utf-8')
  body
    h1
      a(href='/playlist') TWICE
    ul
      each asong in songs_pug
        li
          a(href='/playlist/'+asong.ID)= asong.s_name
    article
      form(action='/playlist/'+song_pug.ID+'/edit' method='post')
        p
          input(type='text' name='title' placeholder='title' value=song_pug.s_name)
        p
          textarea(name='description' placeholder='description')
            =song_pug.s_desc
        p
          input(type='submit' value='edit')

페이지 삭제

페이지삭제는 무조건 post 방식으로 전달되어야 함
(페이지의 모든 링크를 방문하는 플러그인 등이 있을 경우 삭제될 수 있으므로)

app.get('/playlist/:id/delete', function(req,res){
  var sql = 'SELECT ID, s_name FROM twice_song';
  var id = req.params.id;
  conn.query(sql,function(err,songs_app,fields){ // songs_app는 모든 행의 ID, s_name
    var sql ='SELECT * FROM twice_song WHERE id=?';
    conn.query(sql,[id],function(err,song_app,fields){ // song_app은 id가 일치하는 하나의 행
      if(err){ // 에러 o
        console.log(err);
        res.status(500).send('Internal Server Error');
      }
      else { // 에러 x
        if(song_app===0){ // id값이 없는 범위일때 -> 텅 빈 배열, 길이는 0
          console.log('There is no id');
          res.status(500).send('Internal Server Error');
        }
        else {
        res.render('delete',{songs_pug: songs_app, song_pug:song_app[0]})
        }
      }
    });
  });
});
app.post('/playlist/:id/delete', function(req,res){
  var id = req.params.id;
  sql = 'DELETE FROM twice_song WHERE id =?';
  conn.query(sql,[id],function(err,song_app){
    res.redirect('/playlist/');
  })
})

▽ views/delete.pug

doctype html
html
  head
    meta(charset='utf-8')
  body
    h1
      a(href='/playlist') TWICE
    ul
      each asong in songs_pug
        li
          a(href='/playlist/'+asong.ID)= asong.s_name
    article
      h1 Delete? #{song_pug.s_name}
      form(action='/playlist/+song_pug.ID+'delete' method='post')
        p
          input(type='submit' value='YES')
      a(href='/playlist/+song_pug.ID) NO

profile
공부한 것들을 정리하기 위한 용도입니다.

0개의 댓글