我是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);
});
});
};
答案 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运行。
考虑到我认为第一个版本的冗余/冗长是你不喜欢的,只是试图给你一些其他更简洁的方法来做到这一点。希望它有所帮助。