인프런 : https://www.inflearn.com/course/web2-node-js-mysql#
생활 코딩 : https://opentutorials.org/module/3560/21175
유튜브 목록 : https://www.youtube.com/playlist?list=PLuHgQVnccGMAicFFRh8vFFFtLLlNojWUh
소스 : https://github.com/web-n/node.js-mysql
https://github.com/web-n/node.js-mysql/releases/tag/1
준비 및 사용방법
1. 수업 소개
실습 코드
이 수업은 WEB2 - Node.js과 DATABASE2 - MySQL을 기반으로 하고 있습니다. 이를 위한 실습코드가 필요합니다. 아래 주소에 준비해 두었습니다.
2. 실습 준비
Mysql
CREATE database opentutorials; CREATE USER `opentutorials`@`localhost` identified by '1111'; GRANT ALL privileges on opentutorials.* to `opentutorials`@`localhost` ;
CREATE TABLE `author` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `profile` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`) ); -- -- Dumping data for table `author` -- INSERT INTO `author` VALUES (1,'egoing','developer'); INSERT INTO `author` VALUES (2,'duru','database administrator'); INSERT INTO `author` VALUES (3,'taeho','data scientist, developer'); -- -- Table structure for table `topic` -- CREATE TABLE `topic` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(30) NOT NULL, `description` text, `created` datetime NOT NULL, `author_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ); -- -- Dumping data for table `topic` -- INSERT INTO `topic` VALUES (1,'MySQL','MySQL is...','2022-10-01 12:10:11',1); INSERT INTO `topic` VALUES (2,'Oracle','Oracle is ...','2022-10-03 13:01:10',1); INSERT INTO `topic` VALUES (3,'SQL Server','SQL Server is ...','2022-10-20 11:01:10',2); INSERT INTO `topic` VALUES (4,'PostgreSQL','PostgreSQL is ...','2022-10-23 01:03:03',3); INSERT INTO `topic` VALUES (5,'MongoDB','MongoDB is ...','2022-10-30 12:31:03',1);
nodemon 모듈
Node.js 개발 시 자바 스크립트 파일들을 수정 할때마다 매번 ctrl+c를 통해 node를 종료 후 다시 실행해줘야 하는 번거로움 이 있었습니다.
하지만 파일들을 모니터링하고 있다가 수정될 경우 자동으로 서버를 재실행시켜주는 스크립트 모니터링 유틸리티 nodemon를 이용하면 번거로움이 상당히 줄어듭니다
nodemon 설치
npm 1.0Visit Website이상을 사용할 경우 nodemon은 커맨드라인에서 명령어를 사용할 것이기 때문에 -g 옵션을 붙혀서 글로벌로 설치를 합니다.
$ npm install nodemon -g
package.json 간편 설정
간편하게 npm start 명령어로도 nodemon을 실행시킬수 있습니다.
package.json 파일에 다음과 같이 script색션에 등록하면 됩니다.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon ./main.js"
},
실행
$ npm run dev
3. Node.js MySQL 모듈의 기본 사용방법
mysql 설치
$npm i mysql
nodejs/mysql.js
var mysql = require('mysql');
// 비밀번호는 별도의 파일로 분리해서 버전관리에 포함시키지 않아야 합니다.
var connection = mysql.createConnection({
host: 'localhost',
user: 'opentutorials',
password: '1111',
database: 'opentutorials'
});
connection.connect();
connection.query('SELECT * FROM topic', function (error, results, fields) {
if (error) {
console.log(error);
}
console.log('The solution is :', results);
});
connection.end();
4. ER ACCESS DENIED ERROR 오류 처리
My SQL로 구현
5. My SQL로 홈페이지 구현 1
소스코드
main.js (변경사항)
~
var mysql = require('mysql');
var db = mysql.createConnection({
host: 'localhost',
user: 'opentutorials',
password: '1111',
database: 'opentutorials'
});
db.connect();
~
if (pathname === '/') {
if (queryData.id === undefined) {
// fs.readdir('./data', function (error, filelist) {
// var title = 'Welcome';
// var description = 'Hello, Node.js';
// var list = template.list(filelist);
// var html = template.HTML(title, list,
// `<h2>${title}</h2>${description}`,
// `<a href="/create">create</a>`
// );
// response.writeHead(200);
// response.end(html);
// });
db.query("SELeCT * FROM topic", function (error, topics) {
console.log(topics);
response.writeHead(200);
response.end("success");
});
}
~
6. My SQL로 홈페이지 구현 2
소스코드
main.js (변경사항)
main.js
~
db.query("SELeCT * FROM topic", function (error, topics) {
console.log(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);
});
~
lib/template.js
, list: function (topics) {
var list = '<ul>';
var i = 0;
while (i < topics.length) {
list = list + `<li><a href="/?id=${topics[i].id}">${topics[i].title}</a></li>`;
i = i + 1;
}
list = list + '</ul>';
return list;
}
7. My SQL로 상세보기 구현
소스코드
main.js (변경사항)
~
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;
console.log("topic : ", topic);
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);
});
});
}
} else if (pathname === '/create') {
8. My SQL로 글생성 기능 구현
소스코드
main.js (변경사항)
} else if (pathname === '/create_process') {
var body = '';
request.on('data', function (data) {
body = 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, 1], function (error, result) {
if (error) throw error; //등록 처리된 아이디 값 가져오기 insertId
response.writeHead(302, { Location: `/?id=${result.insertId}` });
response.end();
});
});
}
9.My SQL로 글수정 기능 구현 1
소스코드 main.js (변경사항)
} else if (pathname === '/update') {
db.query("select * from topic", function (erro, topics) {
if (erro) throw erro;
db.query(`SELECT * FROM topic WHERE id=?`, [queryData.id], function (error2, topic) {
if (error2) throw error2;
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>
<input type="submit">
</p>
</form>
`,
`<a href="/create" > create</a> <a href="/update?id=${topic[0].id}">update</a>`
);
response.writeHead(200);
response.end(html);
});
});
} else if (pathname === '/update_process') {
10.My SQL로 글수정 기능 구현 2
소스코드 main.js (변경사항)
} else if (pathname === '/update_process') {
var body = '';
request.on('data', function (data) {
body = 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, 1, post.id], function (error, result) {
if (error) throw error;
response.writeHead(302, { Location: `/?id=${post.id}` });
response.end();
});
});
}
11.My SQL로 글 삭제 기능 구현
소스코드
main.js (변경사항)
} else if (pathname === '/delete_process') {
var body = '';
request.on('data', function (data) {
body = 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: `/ ` });
response.end();
});
});
} else {
My SQL join을 이용해서 구현
12.My SQL join을 이용해서 상세보기 구현
main.js (변경사항)
} else {
db.query("SELECT * FROM topic", function (error, topics) {
if (error) throw error;
db.query(`SELECT * FROM topic LEFT JOIN author ON topic.author_id=author.id WHERE topic.id=?`, [queryData.id], function (error2, topic) {
if (error2) throw error2;
console.log("topic : ", topic);
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);
});
});
}
} else if (pathname === '/create') {
13.My SQL join을 이용해서 글 생성 구현
소스코드
변경사항 main.js
} else if (pathname === '/create') {
db.query("SELECT * FROM topic ", function (error, topics) {
db.query("SELECT * FROM author ", function (error2, 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.authorSelect(authors)}
</p>
<p>
<input type="submit">
</p>
</form >
`, '');
response.writeHead(200);
response.end(html);
});
});
} else if (pathname === '/create_process') {
var body = '';
request.on('data', function (data) {
body = 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], function (error, result) {
if (error) throw error; //등록 처리된 아이디 값 가져오기 insertId
response.writeHead(302, { Location: `/? id = ${result.insertId} ` });
response.end();
});
});
} else if (pathname === '/update') {
lib/template.js
}, authorSelect: function (authors) {
var tag = authors.map(author => (
` <option value="${author.id}">${author.name}</option>`
));
return `<select name="author"> ${tag} </select>`;
}
14.My SQL join을 이용해서 글 수정 구현
} else if (pathname === '/update') {
db.query("select * from topic", function (erro, topics) {
if (erro) throw erro;
db.query(`SELECT * FROM topic WHERE id =? `, [queryData.id], function (error2, topic) {
db.query("SELECT * FROM author ", function (error2, authors) {
if (error2) throw error2;
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.authorSelect(authors, topic[0].author_id)}
</p>
<p>
<input type="submit">
</p>
</form>
`,
`<a href = "/create" > create</a > <a href="/update?id=${topic[0].id}">update</a>`
);
response.writeHead(200);
response.end(html);
});
});
});
} else if (pathname === '/update_process') {
var body = '';
request.on('data', function (data) {
body = 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) {
if (error) throw error;
response.writeHead(302, { Location: `/? id = ${post.id} ` });
response.end();
});
});
}
lib/template.js
}, authorSelect: function (authors, author_id) {
var tag = authors.map(author => (
` <option value="${author.id}" ${author.id === author_id ? 'selected' : ''} >${author.name}</option>`
));
return `<select name="author"> ${tag} </select>`;
}
Node.js 정리정돈
15.수업의 정상
16.Node.js의 DB 설정정보 정리정돈
소스코드
변경사항 main.js
var db = require("./lib/db");
./lib/db.js
var mysql = require('mysql');
var db = mysql.createConnection({
host: 'localhost',
user: 'opentutorials',
password: '1111',
database: 'opentutorials'
});
db.connect();
module.exports = db;
17.Node.js 코드의 정리정돈 (topic) -1
소스코드
var topic = require("./lib/topic");
if (queryData.id === undefined) {
topic.home(response);
} else {
lib/topic.js
var template = require('./template.js');
var db = require("./db");
exports.home = function (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);
});
}
18.Node.js 코드의 정리정돈 (topic) -2
소스코드
var pathname = url.parse(_url, true).pathname;
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') {
lib/topic.js
var url = require('url');
var qs = require('querystring');
var template = require('./template.js');
var db = require("./db");
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);
});
}
exports.page = 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 LEFT JOIN author ON topic.author_id=author.id WHERE topic.id=?`, [queryData.id], function (error2, topic) {
if (error2) throw error2;
console.log("topic : ", topic);
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);
});
});
}
exports.create = function (request, response) {
db.query("SELECT * FROM topic ", function (error, topics) {
db.query("SELECT * FROM author ", function (error2, 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.authorSelect(authors)}
</p>
<p>
<input type="submit">
</p>
</form >
`, '');
response.writeHead(200);
response.end(html);
});
});
}
exports.create_process = function (request, response) {
var body = '';
request.on('data', function (data) {
body = 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], function (error, result) {
if (error) throw error; //등록 처리된 아이디 값 가져오기 insertId
response.writeHead(302, { Location: `/? id = ${result.insertId} ` });
response.end();
});
});
}
19.Node.js 코드의 정리정돈 (topic) -3
소스코드
main.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;
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);
response.end('Not found');
}
});
app.listen(3000);
lib/topic.js
var url = require('url');
var qs = require('querystring');
var template = require('./template.js');
var db = require("./db");
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);
});
}
exports.page = 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 LEFT JOIN author ON topic.author_id=author.id WHERE topic.id=?`, [queryData.id], function (error2, topic) {
if (error2) throw error2;
console.log("topic : ", topic);
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);
});
});
}
exports.create = function (request, response) {
db.query("SELECT * FROM topic ", function (error, topics) {
db.query("SELECT * FROM author ", function (error2, 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.authorSelect(authors)}
</p>
<p>
<input type="submit">
</p>
</form >
`, '');
response.writeHead(200);
response.end(html);
});
});
}
exports.create_process = function (request, response) {
var body = '';
request.on('data', function (data) {
body = 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], function (error, result) {
if (error) throw error; //등록 처리된 아이디 값 가져오기 insertId
response.writeHead(302, { Location: `/? id = ${result.insertId} ` });
response.end();
});
});
}
exports.update = function (request, response) {
var _url = request.url;
var queryData = url.parse(_url, true).query;
db.query("select * from topic", function (erro, topics) {
if (erro) throw erro;
db.query(`SELECT * FROM topic WHERE id =? `, [queryData.id], function (error2, topic) {
db.query("SELECT * FROM author ", function (error2, authors) {
if (error2) throw error2;
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.authorSelect(authors, topic[0].author_id)}
</p>
<p>
<input type="submit">
</p>
</form>
`,
`<a href = "/create" > create</a > <a href="/update?id=${topic[0].id}">update</a>`
);
response.writeHead(200);
response.end(html);
});
});
});
}
exports.update_process = function (request, response) {
var body = '';
request.on('data', function (data) {
body = 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) {
if (error) throw error;
response.writeHead(302, { Location: `/? id = ${post.id} ` });
response.end();
});
});
}
exports.delete_process = function (request, response) {
var body = '';
request.on('data', function (data) {
body = 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: `/ ` });
response.end();
});
});
}













댓글 ( 4)
댓글 남기기