iT邦幫忙

DAY 27
5

node.js伺服器實戰系列 第 27

node.js伺服器實戰(27) - 整合資料庫引擎

  • 分享至 

  • xImage
  •  

我自己比較常用的database還是mysql,所以先用他來測試一下在伺服器中使用資料庫引擎。
mysql模組

稍微找了一下資料,目前看起來比較成熟的獨立mysql模組看起來有:

  1. [node-mysql]node-mysql](https://github.com/felixge/node-mysql):這是一個純Javascript的mysql protocol實做
  2. node-mysql-libmysqlclient:這是libmydqlclient程式庫的包裝

其中,node-mysql看起來在不同作業系統跑應該都沒問題,而node-mysql-libmysqlclient看起來好像必須有libmysqlclient,不知道在windows上跑是否沒問題,所以就先拿node-mysql來測試。用npm安裝也很容易,只要在console使用npm install -g mysql就可以安裝好。

驗證

先建立一個測試資料庫(node_test)跟一些測試資料:

 CREATE TABLE IF NOT EXISTS `authors` (
   `id` int(11) NOT NULL auto_increment,
   `name` varchar(20) NOT NULL,
   `email` varchar(30) NOT NULL,
   `group_id` int(11) NOT NULL,
   PRIMARY KEY  (`id`),
   KEY `group_id` (`group_id`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
 INSERT INTO `authors` (`id`, `name`, `email`, `group_id`) VALUES
 (1, 'name1', 'name1@email.com', 1),
 (2, 'name2', 'name2@email.com', 1),
 (3, 'name3', 'name3@yupa.com', 2),
 (4, 'name4', 'name4@yupa.com', 2);
 
 CREATE TABLE IF NOT EXISTS `configs` (
   `id` int(11) NOT NULL auto_increment,
   `name` varchar(20) NOT NULL,
   `value` varchar(255) NOT NULL,
   PRIMARY KEY  (`id`),
   KEY `name` (`name`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
 INSERT INTO `configs` (`id`, `name`, `value`) VALUES
 (1, 'title', 'test for mysql');
 
 CREATE TABLE IF NOT EXISTS `groups` (
   `id` int(11) NOT NULL auto_increment,
   `name` varchar(20) NOT NULL,
   PRIMARY KEY  (`id`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
 INSERT INTO `groups` (`id`, `name`) VALUES
 (1, 'group1'),
 (2, 'group2');

然後用兩個查詢來把資料找出來:

 var mysql = require('mysql');
 var client = mysql.createClient({
     user: 'root',
     password: '',
     host: '127.0.0.1',
     port: '3306',
     database: 'node_test'
 });
 
 function Wait(count, cb) {
     var limit = 0;
     var payload = [];
     this.next = function(data) {
         payload.push(data);
         count--;
         if(count<=0) {
             cb(payload);
         }
     }
 }
 
 var sync = new Wait(2, function(obj) {
     var i=0;
     var ret = {};
     for(; i<obj.length; i++) {
         if(obj[i][0].title) {
             ret.title = obj[i].title;
         } else {
             ret.rows = obj[i]
         }
     }
     console.log(ret);
     client.end();
 });
 
 client.query("SELECT `value` as title FROM `configs` WHERE name='title'", function(err, results, fields) {
     if(!err) {
         sync.next(results);
     } else {
         console.log('err 1.');
     }
 });
 
 client.query("SELECT a.name AS `group`, b.name AS name, b.email AS email FROM groups AS a LEFT JOIN authors AS b ON b.group_id=a.id WHERE 1", function(err, results, fields) {
     if(!err) {
         sync.next(results);
     } else {
         console.log('err 2.');
     }
 });

查詢很簡單,但是結果是用非同步的方式傳給callback,要在兩個查詢結束才回傳結果會有點麻煩。所以把它用一個Wait物件來處理,讓兩個查詢都執行完畢後,才處理查詢的結果。(這類的問題,尤其在資料庫查詢的時候,會常常碰到)

接下來就要執行看看:

 D:\fillano\Dropbox\Shared\tests>node testMysql.js
 { title: undefined,
   rows:
    [ { group: 'group1', name: 'name1', email: 'name1@email.com' },
      { group: 'group1', name: 'name2', email: 'name2@email.com' },
      { group: 'group2', name: 'name3', email: 'name3@yupa.com' },
      { group: 'group2', name: 'name4', email: 'name4@yupa.com' } ] }

看起來查詢的結果符合預期,可以進一步放進伺服器中做測試。

整合

接下來要調整一些檔案來做測試,首先是template檔,在test目錄中新增一個測試用的template,temp2.html,跟temp1.html差不太多,只是跟目前model調整匹配。

 <title>{{title}}</title>
 
 <table border="1" cellspacing="0" cellpadding="2">
 {%for row in rows%}
 <tr><td>{{row.group}}</td><td>{{row.name}}</td><td>{{row.email}}</td></tr>
 {%endfor%}
 </table>
 
 

在vies.js增加一個view:

     "hello_mvc1": function(cb) {
         var view = swig.compileFile('tests/temp2.html');
         this.render = function(data) {
             cb(false, '/hello_mvc1', {type:'text/html', data: view.render(data)});
         };
     }

把剛剛測試的程式加入到models.js中,請參考:https://github.com/fillano/evolve/blob/61db226871bee024cf7bf149c5571811311e487b/tests/models.js 的37~68行。

最後調整testServer.js,在setUp增加一個router:

         .get('/hello_mvc1', function (request, response, cb) {
             var HelloModel = require('./models')['hello_mvc1'];
             var HelloView = require('./views')['hello_mvc1'];
             var m = new HelloModel(new HelloView(cb));
             m.execute();
         })

針對這個router寫一個測試,請參考:
https://github.com/fillano/evolve/blob/61db226871bee024cf7bf149c5571811311e487b/tests/models.js 的230~258行。

然後用ant integrate跑測試,看起來結果OK。

今天的範例檔fillano-evolve-v0.0.20-0-g61db226.zip,目前版本是v0.0.20。

相關文章


上一篇
node.js伺服器實戰(26) - 整合模板引擎
下一篇
node.js伺服器實戰(28) - 進一步釐清伺服器流程
系列文
node.js伺服器實戰33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言