[실습]NodeJS + EXPRESS + MySQL 을 이용한 게시판 만들기 2(MVC)

입력 폼은 따로 작성하지 않고 테스트 진행(필요하면 간단하게 만들 것)
단 form 의 action 은 /posts/new , method 는 post로 작성할 것

테스트 테이블 생성

CREATE TABLE `posts` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(50) NOT NULL COMMENT '작성자 이름' COLLATE 'utf8mb4_unicode_ci',
    `email` VARCHAR(50) NOT NULL COMMENT '작성자 메일주소' COLLATE 'utf8mb4_unicode_ci',
    `password` VARCHAR(255) NOT NULL COMMENT '글 비밀번호' COLLATE 'utf8mb4_unicode_ci',
    `subject` TEXT NULL COMMENT '글 제목' COLLATE 'utf8mb4_unicode_ci',
    `content` LONGTEXT NULL COMMENT '글 내용' COLLATE 'utf8mb4_unicode_ci',
    `like` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT '추천수',
    `hate` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT '반대수',
    `hit` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0' COMMENT '조회수',
    `comment_cnt` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT '코멘트 개수',
    `ip` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'IP',
    `created_at` DATETIME NOT NULL COMMENT '글 작성 시간',
    `updated_at` DATETIME NULL COMMENT '글 수정 시간',
    `deleted_at` DATETIME NULL COMMENT '글 삭제 시간',
    PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB;

추가 모듈 설치

  • bcrypt

    npm install --save bcrypt

컨트롤러 및 모델 등록

mysql 사용법 : https://www.npmjs.com/package/mysql
참고사이트 : 컨트롤러, 모델
참고사이트 모델은 DB 모델링 하는 부분이고 링크 건 부분은 서비스부분

  • app/routes/posts.js

      const express = require('express');
      const router = express.Router();
      const postsController = require('../controllers/postsController');
    
      // list
      router.get('/', postsController.getList);
    
      // New Post Form
      router.get('/new', postsController.getPostForm);
    
      // New Post Process
      router.post('/new', postsController.insertProcess);
    
      module.exports = router;
  • app/controllers/postsController.js

      const postsModel = require('../models/postsModel');
    
      // 리스트
      exports.getList = (req, res) => {
        res.render('posts/list', {
          'title': '게시판 리스트'
        });
      };
    
      // 글 작성 - 폼
      exports.getPostForm = (req, res) => {
        res.render('posts/writeForm', {
          'title': '글 작성하기'
        });
      };
    
      // 글 입력 - 프로세스
    // ip 찾기 - https://wedul.site/520
    exports.insertProcess = (req, res) => {
      let item = {
        'name': req.body.name,
        'email': req.body.email,
        'password': req.body.password,
        'subject': req.body.subject,
        'content': req.body.content,
        'ip': req.headers['x-forwarded-for'] || req.connection.remoteAddress,
        'tags': req.body.tags
      };
      
      postsModel.insertData(item, (result) => {
        if (result) {
          // console.log(result);
          if (result.affectedRows === 1) {
            res.redirect('/posts');
          } else {
            res.redirect('/posts/new');
          }
        }
      });
    };
  • app/models/postsModel.js

      // mysql 연결
      const mysqlConnObj = require('../config/mysql');
      const mysqlConn = mysqlConnObj.init();
      // mysqlConnObj.open(mysqlConn); // 정상적으로 연결되었는지 확인
    
      const bcrypt = require('bcrypt');
      const saltRound = 10;
    
      /**
     * 새로운 글을 작성하면 데이터베이스에 입력한다.
     *
     * data : Input data received from the controller
     * cb : Callback function. After completing input, it returns to the controller
     *
     * @param data
     * @param cb
     */
    exports.insertData = (data, cb) => {
      bcrypt.genSalt(saltRound, (err, salt) => {
        if (err) throw new Error(err);
        
        bcrypt.hash(data.password, salt, (err, hash) => {
          if (err) throw new Error(err);
          
          // 입력 구문
          let now = new Date();
          let sql = 'INSERT INTO posts (name, email, password, subject, content, ip, created_at) VALUES (?, ?, ?, ?, ?, inet_aton(?), ?)';
          let bindParam = [
            data.name,
            data.email,
            hash, // 해싱된 비밀번호
            data.subject,
            data.content,
            data.ip,
            now
          ];
      
          // 참고사이트
          // https://www.npmjs.com/package/mysql
          // https://github.com/gnipbao/express-mvc-framework/blob/master/controllers/task.js
          // https://github.com/gnipbao/express-mvc-framework/blob/master/services/task.js
          mysqlConn.query(sql, bindParam, (err, results, fields) => {
            if (err) {
              console.error('Error code : ' + err.code);
              console.error('Error Message : ' + err.message);
          
              throw new Error(err);
            } else {
              cb(JSON.parse(JSON.stringify(results)));
            }
          });
      
          /**
           * 위 코드에서 result 의 값으로 넘어오는 것들
           *
           *  fieldCount: 0,
           *  affectedRows: 1, // 성공한 개수
           *  insertId: 2,
           *  serverStatus: 2,
           *  warningCount: 0,
           *  message: '',
           *  protocol41: true,
           *  changedRows: 0
           */
        });
      });
    };

서버 실행 및 입력 테스트

+ Recent posts