初衷
增删改查是web开发最常见的操作,那么接下来这篇文章将演示如何用node + mysql做一个简易的网站。
需要的知识
本教程不涉及express等web框架,但请确保您对node + mysql等有基本了解。
需求分析
本网站共有二个页面,主页和副页。
- 主页:
如下图,主页最上面是一个查看存档的按钮,点击会进入副页。上半部分是一个表格,有日期,耗时,描述三个字段,每一列有二个操作,可以存档和删除,存档的记录会从主页中消失,而会在副页中显示,点击删除会彻底删除该列。下半部分是一个表单,由用户输入并提交,提交后的记录出现在上半部分的表格中。
- 副页:
如下图,副页上部是一个表格,有日期,耗时,描述三个字段,每一列只有一个操作,点击删除会彻底删除该列。下部有一个返回按钮,点击会回到主页。
项目目录
- 在根目录下创建app.js,app.js负责
创建http服务器,页面路由控制,登录数据库
等功能 - 在根目录下创建lib文件夹,在lib下新建timetrack.js,其负责
解析post请求,与数据库交互(添加,删除,查看,更新),将服务端渲染的html返回到客户端
等功能 - 安装node的mysql数据库,命令如下:
npm install mysql --save
最终,目录如下所示:
工具准备
mysql数据库:5.7.22
node版本:10.4.1
workbench:6.3 community
数据库部分
首先,打开workbench,登录进去后,新建一个数据库worklist
新建一个sql tab,输入如下命令,创建一个表,用于存储本项目所涉及的数据。
-- sql脚本
CREATE TABLE IF NOT EXISTS work (
id INT(10) NOT NULL AUTO_INCREMENT,
hours DECIMAL(5,2) DEFAULT 0,
date DATE,
archived INT(1) DEFAULT 0,
description LONGTEXT,
PRIMARY KEY(id));
这样,数据库部分就准备好了。
编码
首先,在app.js中输入如下代码:
let http = require('http')
let work = require('./lib/timetrack')
let mysql = require('mysql')
var db = mysql.createConnection({
host: '127.0.0.1',
user: '@your username', // 你的数据库用户名
password: '@your password', // 你的数据库密码
database: 'worklist'
})
var server = http.createServer((req, res) => {
switch (req.method) {
case 'POST':
switch(req.url) {
case '/':
work.add(db, req, res)
break
case '/archive':
work.archive(db, req, res)
break
case '/delete':
work.delete(db, req, res)
break
}
break
case 'GET':
switch (req.url) {
case '/':
work.show(db, res)
break
case '/archived':
work.showArchived(db, res)
break
}
break
}
})
console.log('Server started...')
server.listen(3000, '127.0.0.1')
接着,在lib目录下的timetrack.js中输入如下代码:
var qs = require('querystring')
// 1 show
exports.show = function (db, res, showArchived) {
let archiveValue = (showArchived) ? 1 : 0
db.query(
'SELECT * FROM work WHERE archived = ? ORDER BY date DESC',
[archiveValue],
function (err, rows) {
if (err) {
throw err
}
if (showArchived) { // 副页
html = (showArchived) ? '' : '<a href="/archived">查看存档</a><br/>'
html += exports.workHitlistHtml(rows)
html += '<a href="/">返回</a>'
} else { // 主页
html = (showArchived) ? '' : '<a href="/archived">查看存档</a><br/>'
html += exports.workHitlistHtml(rows)
html += exports.workFormHtml()
}
exports.sendHtml(res, html)
}
)
}
// 显示上半部分--列表
exports.workHitlistHtml = function (rows) {
var html = '<table>'
for(var i in rows) {
html += '<tr>'
html += '<td>' + rows[i].date + '</td>'
html += '<td>' + rows[i].hours + '</td>'
html += '<td>' + rows[i].description + '</td>'
if (!rows[i].archived) {
html += '<td>' + exports.workArchiveForm(rows[i].id) + '</td>'
}
html += '<td>' + exports.workDeleteForm(rows[i].id) + '</td>'
html += '</tr>'
}
html += '</table>'
return html
}
// 显示下半部分--提交
exports.workFormHtml = function () {
var html = '<form method="POST" action="/">' +
'<p>日期 (YYYY-MM-DD):<br/><input name="date" type="text"><p/>' +
'<p>耗时:<br/><input name="hours" type="text"><p/>' +
'<p>描述:<br/>' +
'<textarea name="description"></textarea></p>' +
'<input type="submit" value="添加" />' +
'</form>'
return html
}
// 返回到浏览器
exports.sendHtml = function (res, html) {
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
res.setHeader('Content-Length', Buffer.byteLength(html))
res.end(html)
}
// 渲染二个操作 -- 存档和删除
exports.workArchiveForm = function (id) {
return exports.actionForm(id, '/archive', '存档')
}
exports.workDeleteForm = function (id) {
return exports.actionForm(id, '/delete', '删除')
}
exports.actionForm = function (id, path, label) {
var html = '<form method="POST" action="' + path + '">' +
'<input type="hidden" name="id" value="' + id + '">' +
'<input type="submit" value="' + label + '" />' +
'</form>'
return html
}
// 2 add
exports.add = function (db, req, res) {
exports.parseReceivedData(req, function(work) {
db.query(
'INSERT INTO work (hours, date, description) VALUES (?, ?, ?)',
[work.hours, work.date, work.description],
function (err) {
if (err) throw err
exports.show(db, res)
}
)
})
}
// 解析post请求
exports.parseReceivedData = function (req, cb) {
var body = ''
req.setEncoding('utf8')
req.on('data', chunk => {
body += chunk
})
req.on('end', () => {
var data = qs.parse(body)
cb(data)
})
}
// 3 存档
exports.archive = function (db, req, res) {
exports.parseReceivedData(req, function(work) {
db.query(
"UPDATE work SET archived = 1 WHERE id = ?",
[work.id],
function (err) {
if (err) throw err
exports.show(db, res)
}
)
})
}
// 4 删除
exports.delete = function (db, req, res) {
exports.parseReceivedData(req, function (work) {
db.query(
"DELETE FROM work WHERE id = ?",
[work.id],
function (err) {
if (err) throw err
exports.show(db, res)
}
)
})
}
// 5 查看存档
exports.showArchived = function (db, res) {
exports.show(db, res, true)
}
运行
终端中输入如下命令:node app
开启http服务器,然后在浏览器URL中输入http://localhost:3000/
即可
注意
1 在运行http服务器之前,请确保数据库服务已经开启,否则会报错。
2 在主页中输入日期时,请确保格式如:2017-03-06,而不是其他格式,否则,数据库会报错:Incorrect date value
参考
mysql5.7文档 https://dev.mysql.com/doc/ref...
workbench基本操作 https://blog.csdn.net/souland...
SQL基础教程 https://book.douban.com/subje...
Node.js实战 https://book.douban.com/subje...
mysql模块 https://github.com/mysqljs/mysql