0

任何人都可以解释为什么我放在 MySql 数据库中的字符串变成了一个不可用的对象?我该如何解决?

注意:我正在使用 Nodejs。表项是 (id = VARCHAR and data = BLOB)

JSONf 类似于 JSON,但它也可以用于函数。

item = {"id":"myitem",
        "option":[  (function(key){ craftItem(key,{"piece":"armor"},{"item":[]});}),
                    (function(key){ test2(key);})
        ]};

str = JSONf.stringify(item); //str = {"id":"myitem","option":["function (key){ craftItem(key,{\"piece\":\"armor\"},{\"item\":[]});}","function (key){ test2(key);}"]}
console.log(typeof str);    //string
obj = JSONf.parse(str);
obj.option[1]();    //calling the method as expected

//Note: data is blob type in MySql
client.query("INSERT INTO item(id,data) VALUES ('" + item.id + "','" +     JSONf.stringify(item) + "')",
function(err, results) {    if(err) throw err 
    client.query("SELECT * FROM item WHERE id='" + item.id + "'" ,function(err,     results) {
        str = results[0].data;
        console.log(str);   //<Buffer 7b 22 69 64 22 3a 22 6d 79 69 74 65 6d 22 2c 22 6f 70 74 69 6f 6e 22 3a 5b 22 66 75 6e...
        console.log(typeof str);    //Object?...

        obj = JSONf.parse(str); //ERROR: Unexpected token p
        //Note: p is probably from the ' craftItem(key,{\"piece\":\"armor\"} '
        obj.option[1](); //never called because program crashed...

});

});

JSONf.stringify = function(obj) {
return JSON.stringify(obj,function(key, value){
    return (typeof value === 'function' ) ? value.toString() : value;
});
}

JSONf.parse = function(str) {
return JSON.parse(str,function(key, value){
    if(typeof value != 'string') return value;
    return ( value.substring(0,8) == 'function') ? eval('('+value+')') : value;
});
}
4

2 回答 2

1

如果您不想将架构更改为由驱动程序序列化为字符串的类型(这基于字段类型,如 TEXT 与 BLOB 和字符集 - 如果它是“二进制”,则使用缓冲区),那么您可以转换结果为字符串:

str = results[0].data.toString(); // array of bytes interpreted as utf8 sequence and converted to JS string

此外,您正在手动将数据与查询连接起来。您需要添加转义 ( connection.escape()),或者更好的是,使用内置的参数化支持:

代替

client.query("SELECT * FROM item WHERE id='" + item.id + "'" ,function(err, res) {
   ///
});

你应该做

client.query("SELECT * FROM item WHERE id=?", [item.id] ,function(err, res) {
   ///
});

或者

client.execute("SELECT * FROM item WHERE id=?", [item.id] ,function(err, res) {
   ///
});

如果你想使用准备好的语句(在node-mysql2中支持)

于 2013-09-06T05:22:05.587 回答
1

好吧,您保存到一个只是字节集合的 blob 字段。在节点中,这表示为一个缓冲区对象。您可能想要做的是将字段的 mysql 数据类型从BLOB这种TEXT方式更改为对数据施加字符编码。这样返回的对象应该是一个可以解析的字符串。

在相关说明中,您确定要将数据序列化到数据库中。这种首先违背了使用数据库的目的,因为您无法有效地对序列化数据进行索引/排序等。

编辑:

另请注意,如果您在节点文档上查找缓冲区对象,则该对象并非不可用,您可以将 Buffer 转换回字符串对象。但是,如果您存储文本而不是图像等二进制数据,则最好使用TEXT

于 2013-09-05T20:44:56.833 回答