標籤:
為了瞭解在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
用MySQL構建一個工作跟蹤流程