nodejs解析mysql行到对象

时间:2014-02-19 23:50:50

标签: mysql node.js

我是node.js + mysql +面向对象的新手。

关注问题here我希望'Content'对象使用mysql查询返回的值。我现在正在做什么我发现它真的是多余的,可能是愚蠢的,因为rows [0]本身就是我想要使用的对象。有没有更好的方法呢?或者不同的方法,如果这是错误的也赞赏。

(我正在使用二进制uuid密钥,必须再次使用十六进制字符串作为资源响应发送)

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

1 个答案:

答案 0 :(得分: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]));
  });

你'也可以'直接抓取rows [0]对象,或多或少原位HEX UUID并修改对​​象的__proto__,或者在Harmony / 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运行。

考虑到我认为第一个版本的冗余/冗长是你不喜欢的,只是试图给你一些其他更简洁的方法来做到这一点。希望它有所帮助。