用MySQL构建一个工作跟踪流程

为了了解在Node中如何使用MySQL,我们来看一个需要RDBMS的程序。

假设你要创建一个Web程序,用来记录你是如何度过工作日的。这需要记录工作的日期,花在工作上的时间,以及工作完成情况的描述。

1. 系统分析

1.1 系统流程

  • 这个程序会有个表单,用来输入工作的详细信息,如图:

    ?

  • 工作信息输入后,可以被归档或删除,让它不再显示在用来输入更多工作的输入域上方,如图。
  • 点击“Archived Work”链接可以把之前归档的工作项全部显示出来。

    ?

1.2 系统任务

  • 创建程序逻辑
  • 创建程序工作所需的辅助函数
  • 编写让你可以用MySQL添加、删除、更新和获取数据的函数
  • 编写渲染HTML记录和表单的代码

1.3 使用模块

这个程序会用Node内置的http模块实现Web服务器的功能,用一个第三方模块跟MySQL服务器交互。一个名为timetrack的定制模块,它是程序特有的函数,用来在MySQL中存储、修改和获取数据。图5-4是这个程序的概览。

先用下面这条命令安装这个很受欢迎的MySQL Node模块:

npm install mysql

?

1.4 最终效果

最终结果如图5-5所示,一个可以用来记录所做工作的简单Web程序,还可以回顾、归档及删除工作记录。

?

2. 创建程序的逻辑

接下来需要创建两个文件存放程序逻辑。这个两个文件分别是: timetrack_server.js,用来启动程序; timetrack.js,包含程序相关功能的模块。

先创建timetrack_server.js,把代码清单5-7中的代码放到里面。这段代码包含Node的HTTPAPI,程序特定的逻辑以及MySQL API。根据你的MySQL配置填入host、 user和password这些设定值。

var http = require( ‘http‘ ) ;
var work = require( ‘./lib/timetrack‘ ) ;
var mysql = require( ‘mysql‘ ) ;

var db = mysql.createConnection( {
    host: ‘127.0.0.1‘,
    user: ‘root‘,
    password: ‘root‘,
    database: ‘timetrack‘
} ) ;

接下来添加代码清单5-8中的逻辑,定义Web程序的行为。用这个程序可以浏览、添加和删除工作执行记录。此外还可以归档工作记录。被归档的工作记录不再出现在主页面上,但还可以在一个单独的Web页面上浏览。

var server = http.createServer( function (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 ;
        }
    }
} ) ;

代码清单5-9是timetrack_server.js中的最后一块代码。这段代码创建了一个数据库表(如果不存在的话) , 启动HTTP服务器,监听本机的3000端口。所有的node-mysql查询都用query函数执行。

db.query(
    ‘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) )‘,
    function (err) {
        if (err) throw err ;
        console.log( ‘Server started...‘ ) ;
        server.listen( 3000, ‘127.0.0.1‘ ) ;
    }
) ;

3. 创建辅助函数发送HTML,创建表单,接收表单数据

启动程序的文件已经完成,该创建定义程序其他功能的文件了。创建一个名为lib的目录,然后在这个目录下创建文件timetrack.js。把代码清单5-10中的代码放到这个文件中,其中包含Node querystring API,并定义了辅助函数,用来发送Web页面HTML,接收通过表单提交的数据。

npm install querystring
var qs = require( ‘querystring‘ ) ;

exports.sendHtml = function (res, html) {
    res.setHeader( ‘Content-Type‘, ‘text/html‘ ) ;
    res.setHeader( ‘Content-Length‘, Buffer.byteLength( html ) ) ;
    res.end( html ) ;
} ;

exports.parseReceivedData = function (req, cb) {
    var body = ‘‘ ;
    req.setEncoding( ‘utf8‘ ) ;
    req.on( ‘data‘, function (chunk) {
        body = chunk ;
    } ) ;
    req.on( ‘end‘, function () {
        var data = qs.parse( body ) ;
        cb( data ) ;
    } ) ;
} ;

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 ;
} ;

4. 用MySQL添加数据

辅助函数到位了,该编写往MySQL数据库里添加工作记录的代码了。把下面代码清单里的代码添加到timetrack.js中。

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 ) ;
            }
        ) ;
    } ) ;
} ;

注意上面代码中的问号(?),这是用来指明应该把参数放在哪里的占位符。在添加到查询语句中之前, query方法会自动把参数转义,以防遭受到SQL注入攻击。此外还要留意一下query方法的第二个参数,是一串用来替代占位符的值。

5. 删除MySQL数据

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 ) ;
            }
        ) ;
    } ) ;
} ;

6. 更新MySQL数据

为了实现更新工作记录的逻辑,将它标记为已归档,把下面的代码添加到timetrack.js中。

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 ) ;
            }
        ) ;
    } ) ;
} ;

7. 获取MySQL数据

添加、删除、更新工作记录的逻辑已经定义好了,现在可以把代码清单5-14中的逻辑添加到到timetrack中,用来获取工作记录数据(归档的或未归档的),从而把它渲染为HTML。在发起查询时传入了一个回调函数,它的参数rows是用来保存返回的查询结果的。

exports.show = function (db, res, showArchived) {
    console.log( ‘in show function‘ ) ;
    var query = ‘select * from work ‘ +
       ‘where archived = ? ‘ +
       ‘order by date desc ‘ ;
    var archiveValue = (showArchived) ? 1 : 0 ;
    console.log( ‘archiveValue:‘ + archiveValue ) ;
    db.query(
        query,
        [archiveValue],
        function (err, rows) {
            console.log( rows ) ;
            if (err) throw err ;
            html = (showArchived)
                ? ‘‘
                : ‘<a href="/archived">Archived Work</a><br/>‘ ;
            html += exports.workHitlistHtml( rows ) ;
            html += exports.workFormHtml() ;
            exports.sendHtml(res, html) ;
        }
    ) ;
} ;

exports.showArchived = function (db, res) {
    exports.show(db, res, true) ;
}

8. 渲染MySQL记录

将下面代码清单中的代码添加到timetrack.js中。它会将工作记录渲染为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 += ‘</table>‘ ;
    return html ;
} ;

9. 渲染HTML表单

exports.workFormHtml = function () {
   var html = ‘<form method="POST" action="/">‘ +
       ‘<p>Date (YYYY-MM-DD):<br/><input name="date" type="text"></p>‘ +
       ‘<p>Hours worked:<br/><input name="hours" type="text"></p>‘ +
       ‘<p>Description:<br>‘ +
       ‘<textarea name="description"></textarea></p>‘ +
       ‘<input type="submit" value="Add">‘ +
       ‘</form>‘ ;
    return html ;
} ;

exports.workArchiveForm = function (id) {
    return exports.actionForm(id, ‘/archive‘, ‘Archive‘) ;
} ;

exports.workDeleteForm = function (id) {
    return exports.actionForm( id, ‘/delete‘, ‘Delete‘ ) ;
} ;

10. 试一下

程序已经做完了,现在可以运行了。记得先用MySQL管理工具创建名为timetrack的数据库。然后在命令行中用下面的命令启动程序:

node timetrack_server.js

最后在浏览器中访问http://127.0.0.1:3000

时间: 2024-08-01 03:39:28

用MySQL构建一个工作跟踪流程的相关文章

用C语言构建一个可执行程序的流程

1.流程图 从用C语言写源代码,然后经过编译器.连接器到最终可执行程序的流程图大致如下图所示. 2.编译流程 首先,我们先用C语言把源代码写好,然后交给C语言编译器.C语言编译器内部分为前端和后端. 2.1 编译器前端 前端负责将C语言代码进行词法和语法上的解析,然后可以生成中间代码. 中间代码这部分不是必须的,但是它能够为程序的跨平台移植带来诸多好处.比如,同样的一份C语言源代码在一台计算机上编译完之后,生成一套中间代码.然后针对不同的目标平台(比如要将这一套代码分别编译成 ARM 处理器的二

[转载] 利用flume+kafka+storm+mysql构建大数据实时系统

原文: http://mp.weixin.qq.com/s?__biz=MjM5NzAyNTE0Ng==&mid=205526269&idx=1&sn=6300502dad3e41a36f9bde8e0ba2284d&key=c468684b929d2be22eb8e183b6f92c75565b8179a9a179662ceb350cf82755209a424771bbc05810db9b7203a62c7a26&ascene=0&uin=Mjk1ODMy

基于rsyslog+mysql+loganalyzer构建一个小而美的日志服务器

前言: 每当我们遇到问题抓耳挠腮,一脸懵那啥的时候,也许看一下日志就瞬间豁然开朗,所以,一个易用的日志服务器还是很重要的.我们先不介绍elk,那个牛逼吊炸天的日志分析系统.今天我们先来构建一个小的日志服务器.elk我们以后再说~ 正文: 当我们配置完一个服务,启动报错时,那感觉就像吃了啥一样,别提多难受,除非服务程序本身有检测配置文件的程序,不然我们就得依赖linux自己的集中日志服务器rsyslog了.不过,有时候也许我们想搜索一下某条日志,或者向用可视化的界面进行统计分析.此时我们可以把日志

为您的Web项目构建一个简单的JSON控制器

摘要:无论您的项目使用的是哪种数据库后端,JavaScript Object Notation (JSON) 控制器都能简化您的开发工作.本文将带领您建立一个能够增强您的下一个开发项目的非常基础的 JSON 控制器. 您的下一个 PHP/MySQL 项目可能与您最近完成的十几个项目类似:建立一个 MySQL 数据库,创建包含 HTML 的 PHP 视图,根据需要添加 JavaScript 代码和 CSS 文件,连接到数据库,从数据库提取内容来填充视图,等等.如果您熟悉 web 开发,您一定知道分

如何基于Python构建一个可扩展的运维自动化平台

嘉宾简介 刘天斯 从事互联网运维工作已13年,目前就职于腾讯-互动娱乐部,负责游戏大数据的运营,曾就职于天涯社区,担任首席架构师/系统管理员. 热衷开源技术的研究,包括系统架构.运维开发.负载均衡.缓存技术.数据库.NOSQL.分布式存储.消息中间件.大数据及云计算.Mesos.Docker.DevOps等领域.擅长大规模集群的运维工作,尤其在自动化运维方面有着非常丰富的经验.同时热衷于互联网前沿技术的研究,活跃在国内社区.业界技术大会,充当一名开源技术的传播与分享者. 导言 受 Reboot

用 Go 构建一个区块链 -- Part 7: 网络

引言 到目前为止,我们所构建的原型已经具备了区块链所有的关键特性:匿名,安全,随机生成的地址:区块链数据存储:工作量证明系统:可靠地存储交易.尽管这些特性都不可或缺,但是仍有不足.能够使得这些特性真正发光发热,使得加密货币成为可能的,是网络(network).如果实现的这样一个区块链仅仅运行在单一节点上,有什么用呢?如果只有一个用户,那么这些基于密码学的特性,又有什么用呢?正是由于网络,才使得整个机制能够运转和发光发热. 你可以将这些区块链特性认为是规则(rule),类似于人类在一起生活,繁衍生

步步深入:MySQL架构总览-&gt;查询执行流程-&gt;SQL解析顺序

前言: 一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇博文了. 本文将从MySQL总体架构--->查询执行流程--->语句执行顺序来探讨一下其中的知识. 一.MySQL架构总览: 架构最好看图,再配上必要的说明文字. 下图根据参考书籍中一图为原本,再在其上添加上了自己的理解. 从上图中我们可以看到,整个架构分为两层,上层是MySQLD的被称为的‘SQL Layer’,下层是各种各样对上提供接口的存储引擎,被称为‘Storage Engin

MySQL架构总览-&gt;查询执行流程-&gt;SQL解析顺序

前言: 一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇博文了. 本文将从MySQL总体架构--->查询执行流程--->语句执行顺序来探讨一下其中的知识. 一.MySQL架构总览: 架构最好看图,再配上必要的说明文字. 下图根据参考书籍中一图为原本,再在其上添加上了自己的理解. 从上图中我们可以看到,整个架构分为两层,上层是MySQLD的被称为的'SQL Layer',下层是各种各样对上提供接口的存储引擎,被称为'Storage Engin

从零构建一个简单的 Python Web框架

为什么你想要自己构建一个 web 框架呢?我想,原因有以下几点: 你有一个新奇的想法,觉得将会取代其他的框架 你想要获得一些名气 你遇到的问题很独特,以至于现有的框架不太合适 你对 web 框架是如何工作的很感兴趣,因为你想要成为一位更好的 web 开发者. 接下来的笔墨将着重于最后一点.这篇文章旨在通过对设计和实现过程一步一步的阐述告诉读者,我在完成一个小型的服务器和框架之后学到了什么.你可以在这个代码仓库中找到这个项目的完整代码. 我希望这篇文章可以鼓励更多的人来尝试,因为这确实很有趣.它让