2014-02-19 63 views
0

我是一個在node.js + mysql +面向對象的新手。nodejs解析mysql行到對象

以下問題here我希望'Content'對象使用由mysql查詢返回的值。現在我在做什麼,我發現它真的是多餘的,可能是愚蠢的,因爲行[0]本身就是我想要使用的對象。任何更好的方式來做到這一點?或者如果這是不對的方法也值得讚賞。

(我使用的是二進制UUID鍵必須是十六進制stringifyed再次爲資源響應發送)

content.js:

function Content() { 
    this.id = ''; 
    this.name = ''; 
    this.domain = ''; 
} 

Content.prototype.validate = function(path, queryParams) { 
    ... 
    return true; 
}; 

Content.prototype.whatever = function(apiVersion, params, callback) { 
    ... 
    return callback(null, newParams); 
}; 

mysql.js:

MySQLDb.SELECT_CONTENT_ID = "SELECT id, name, domain FROM content WHERE id = UNHEX(?)"; 

MySQLDb.prototype.findContentByID = function(id, callback) { 
    this.dbConnection.query(MySQLDb.SELECT_CONTENT_ID, [ id ], 
     function(err, rows, fields) { 
     var content = new Content(); 

     if (rows.length > 0) { 
      var i = 0; 
      for (var key in rows[0]) { 
      if (rows[0].hasOwnProperty(key) && content.hasOwnProperty(key)) { 
       // BINARY(16) --> HEX string 
       if (fields[i].columnType === 254) { 
       content[key] = rows[0][key].toString('hex').toUpperCase(); 
       } else { 
       content[key] = rows[0][key]; 
       } 
      } else { 
       console.log('Column ' + key + ' out of sync on table "content"'); 
      } 

      i += 1; 
      } 
     } 

     callback(err, content); 
     }); 
}; 

contentRes.js:

contentRes.GETWhatever = function(req, res) { 
    db.findContentByID(req.params.id, function onContent(err, content) { 
    if (err || !content.validate(req.path, req.query)) { 
     return res.send({}); 
    } 

    content.whatever(req.query.apiVersion, req.query.d, 
     function onWhateverdone(err, params) { 
      if (err) { 
      return res.send({}); 
      } 

      return res.send(params); 
     }); 
    }); 
}; 

回答

0

我想很多人都會說,儘管它確實感覺多餘,但一般都是正確的。

,如果你重構你的代碼,你可以調用Content()構造一個可選的對象,在這種情況下rows[0]但如果你是保持清潔,你不會有機會獲得fields所以你也許覺得有點清潔會採取不同的方法來進行數據類型轉換 - 通過在查詢中選擇HEX表示或者只需讓Content()知道它需要轉換id屬性。

保持它相當簡單(我指的是無視使得構造有點更智能以及任何錯誤檢測或處理),你會:

function Content(baseObj) { 
    this.id = (baseObj && baseObj.id) ? baseObj.id.toString('hex').toUpperCase() : ''; 
    this.name = (baseObj && baseObj.name) ? baseObj.name : ''; 
    this.domain = (baseObj && baseObj.domain) ? baseObj.domain : ''; 
} 

然後,你可以這樣做:

MySQLDb.prototype.findContentByID = function(id, callback) { 
    this.dbConnection.query(MySQLDb.SELECT_CONTENT_ID, [ id ], 
    function(err, rows, fields) { 
    if (err) return callback(err,null); 
    return callback(err, new Content(rows[0])); 
    }); 

你「可能」也搶行[0],HEX的UUID或多或少原位直接對象,並修改對象的__proto__,或下和聲/ ES6使用setPrototypeOf()方法。

MySQLDb.prototype.findContentByID = function(id, callback) { 
    this.dbConnection.query(MySQLDb.SELECT_CONTENT_ID, [ id ], 
    function(err, rows, fields) { 
    if (err) return callback(err,null); 
    var content = rows[0]; 
    content.id = content.id.toString('hex').toUpperCase(); 
    content.__proto__ = Content.prototype; 
    return callback(err, content); 
    }); 

請注意,我說你'可以'這樣做。合理的人可以不同,你是否應該這樣做。 __proto__已被棄用(雖然它從我所見過的Node中工作得很好)。如果你採用這種一般方法,我可能會建議使用setPrototypeOf(),並安裝一個polyfill,直到你用ES6運行。

只是試圖給你一些其他更簡潔的方法來做到這一點,因爲我認爲第一個版本的冗餘/冗長是你不喜歡的。希望能幫助到你。

+0

謝謝巴里。我仍然覺得這是多餘的,但這是我如何結束的。事實上,我在單例類中插入了mysql連接,其餘的類調用了mysql.query()(它調用dbConnection.query()) – Miquel

+0

不客氣。這種方法(單例)確實擺脫了至少一些冗餘樣板。我非常同情試圖簡化/簡化數據庫處理代碼。 –