Node JS Web Mysql

Node & mysql 연결

npm 에서 mysql을 다운받아 주고 package.json 의 dependencies에 mysql을 설정해준다.

npm install --S mysql

DB를 연결해주고 DB정보를 설정하는 javascript를 만들어준다.

(lib 폴더에 db.js를 만들어주고 안에 아래와 같이 설정을 적용시켜준다)
var  mysql = require("mysql"); //아까 인스톨한 mysql을 require해준다
var  db = mysql.createConnection({ //createConnection()을 설정하고 host, user, password, 사용할 database를 적어준다.
	host:  "localhost",
	user:  "root",
	password:  "system",
	database:  "opentutorials",
});
db.connect();	//db를 연결해준다.

module.exports = db;	// 해당 db.js를 exprots 해준다 (외부에서 사용하게끔)

이때까지 파일을 load하여 페이지를 만들고 데이터를 읽어 온것을 모두 db 형식으로 교체한다.

또한 이전 main.js에 모두 담겨있던 코드들을 따로 빼서 관리 하도록 리펙토링 하였다. 아래 코드들은 모두 따로 리펙토링하였으며, exports하였다.

// topic.js
var  db = require("./db");
var  template = require("./template.js");
var  url = require("url");
var  qs = require("querystring");

우선 필요한 모듈들을 가져온다.

// home
exports.home = function (request, response) {
	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);
	});
};

//page
exports.page = function (request, response) {
	var  _url = request.url;
	var  queryData = url.parse(_url, true).query;
	db.query(`SELECT *FROM topic`, function (error, topics) { 
	//db쿼리를 SELECT* FROM topic으로 하여 모든 내용을 가져오게 한다. (목록을 뿌려주기 위해 데이터를 가져오는 부분)
		if (error) {
		throw  error;
		}
		db.query(
			`SELECT * FROM topic LEFT JOIN author ON topic.author_id = author.id WHERE topic.id =?`,
			// join을 사용하여 저자 id와 topic의 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}
				<p>by ${topic[0].name}</p>
				`,
				`<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);
			}
		);
	});
};
// create 부분
exports.create = function (request, response) {
	db.query(`SELECT *FROM topic`, function (error, topics) {
		db.query(`SELECT * FROM author`, function (error2, authors) {
		// 저자의 목록을 가져오고 authors에 담아 마지막 템플릿의 authors에 넣어준다.
			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>
			${template.authorSelct(authors)}
			</p>
			<p><input type="submit"></p></from>`,
			`<a href="/create">create</a>`
		);
		response.writeHead(200);
		response.end(html);
		});
	});
};
//create_process 부분
exports.create_process = function (request, response) {
	var  body = "";
	request.on("data", function (data) {
		body += data;
	});
	request.on("end", function () {
		var  post = qs.parse(body);
		db.query(
			`INSERT INTO topic (title, description, created, author_id) VALUES(?, ?, NOW(), ?)`,
			[post.title, post.description, post.author],// 쿼리의 title, description과 author을 ?에 순서에 맡게 넣는다.
			function (error, result) {
				if (error) {
					throw  error;
				}
				response.writeHead(302, { Location:  `/?id=${result.insertId}` }); //callback에 result로 insertId로 방금 추가한 데이터의 id로 접근하여 페이지로 이동
				response.end();
			}
		);
	});
};

//update
exports.update = function (request, response) {
	var  _url = request.url;
	var  queryData = url.parse(_url, true).query;
	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;
				}
				db.query(`SELECT * FROM author`, function (error2, authors) {
					var  list = template.list(topics);
					var  html = template.html(
					topic[0].title,
					list,
					`<form action="/update_process" method="post">
					<input type="hidden" name="id" value="${topic[0].id}"
					<p><input type="text" name ="title" placeholder="title" value="${
					topic[0].title
					}"></p>
					<p><textarea name="description" placeholder="description">${
					topic[0].description
					}</textarea></p>
					<p>
					${template.authorSelct(authors, topic[0].author_id)}
					</p>
					<p><input type="submit"></p>`,
					`<a href="/create">create</a> <a href="/update?id=${topic[0].id}">update</a>`
				);
				response.writeHead(200);
				response.end(html);
				});
			}
		);
	});
};
//update_process
exports.update_process = function (request, response) {
	var  body = "";
	request.on("data", function (data) {
		body += data;
	});
	request.on("end", function () {
		var  post = qs.parse(body);
		db.query(
			`UPDATE topic SET title = ?, description = ?, author_id=? WHERE id = ?`,
			[post.title, post.description, post.author, post.id],
			function (error, result) {
			response.writeHead(302, { Location:  `/?id=${post.id}` }); //302은 변경된 페이지고 redirect
			response.end();
			}
		);
	});
};
// delete_process
exports.delete_process = function (request, response) {
	var  body = "";
	request.on("data", function (data) {
		body += data;
	});
	request.on("end", function () {
		var  post = qs.parse(body);
		db.query(
		"DELETE FROM topic WHERE id =?",
		[post.id],
		function (error, result) {
			if (error) {
				throw  error;
			}
			response.writeHead(302, { Location:  `/` }); //302은 변경된 페이지고 redirect
			response.end();
			}
		);
	});
};

template.js 에는 이전 템플릿과 저자를 선택할 수 있는 폼도 만들어준다.

module.exports = {

html:  function (title, list, body, control) {

return  `

<!doctype html>

<html>

<head>

<title>WEB1 - ${title}</title>

<meta charset="utf-8">

</head>

<body>

<h1><a href="/">WEB</a></h1>

${list}

${control}

${body}

</body>

</html>

`;

},

list:  function (topics) {

var  list = "<ul>";

var  i = 0;

while (i < topics.length) {

list += `<li><a href="/?id=${topics[i].id}">${topics[i].title}</a></li>`;

i++;

}

list = list + "</ul>";

return  list;

},authorSelct:function(authors, author_id){

var  tag = "";

var  i = 0;

while(i < authors.length){

var  selected = '';

if(authors[i].id === author_id){

selected = ' selected'; //수정 페이지에서 만약 반복문을 돌리던 도중 저자 아이디 같은것이 나온다면 선택의 속성을 부여

}

tag += `<option value="${authors[i].id}"${selected}>${authors[i].name}</option>`;

i++;

}

return`

<select name="author">

${tag}

</select>

`

}

};

main.js에는 이제 topic.js와 template.js의 모듈들을 가져와 각 사용자가 원하는 페이지로 요청하였을때 생성 할 수 있도록 조건문으로 구성해 준다.

var  http = require("http");
var  url = require("url");
var  topic = require("./lib/topic");
  
var  app = http.createServer(function (request, response) {
	var  _url = request.url;
	var  queryData = url.parse(_url, true).query;

	var  pathname = url.parse(_url, true).pathname; //path(쿼리 제외)
	if (pathname === "/") {
		if (queryData.id === undefined) {
			topic.home(request, response);
		} else {
			topic.page(request, response);
		}
	} else  if (pathname === "/create") {
		topic.create(request, response);
	} else  if (pathname === "/create_process") {
		topic.create_process(request, response);
	} else  if (pathname === "/update") {
		topic.update(request, response);
	} else  if (pathname === "/update_process") {
		topic.update_process(request, response);
	} else  if (pathname === "/delete_process") {
		topic.delete_process(request, response);
	} else {
		response.writeHead(404); //웹서버가 응답할때 200은 브라우저는 성공 이라는 의미, 404 는 에러
		response.end("Not found");
	}
});
app.listen(3000);