如何从 Nodejs Mysql 中获取 JSON 类型 JSON 而不是 String

How to get JSON type as JSON instead of String from Nodejs Mysql

我 table 在 MySQL 5.7

中说 TEST(id INT, attribute JSON)

当我尝试使用 mysql 包在 Nodejs 中查询 table 时,如下所示

con.query("select * from TEST where id=?", [req.params.id], function (err, results) {
    if (err) throw err;
    console.log(results);
  });

我得到以下输出

[
   {
        "id": 2,
        "package": "{\"tag\": \"tag1\", \"item\": \"item1\"}"
    }
]

有没有办法在不迭代数组的情况下将上述结果中的包项作为JSON对象而不是字符串,然后JSON.parse将字符串转换为JSON?

预期输出

[
       {
            "id": 2,
            "package": {"tag": "tag1", 
                        "item": "item1"}
        }
    ]

我想你只需要JSON.parse(results)

con.query("select * from TEST where id=?", [req.params.id], function (err, results) {
if (err) throw err;
console.log(JSON.parse(results));

});

编辑!评论者指出您需要遍历结果,我的回答很草率,行不通:

con.query("select * from TEST where id=?", [req.params.id], function (err, results) {
if (err) throw err;
results = results.map(row => (row.package = JSON.parse(row.package), row));

});

Is there a way to get the package item in the above result as JSON object instead of a string without iterating the array and do JSON.parse to convert string to JSON?

MySQL 5.7 支持 JSON data type,因此您可以将包类型更改为 JSON,并且不必在每一行上迭代和执行 JSON.parse,如果您的客户端支持此数据类型。

请记住 mysql package does not support it, but mysql2 会。

CREATE TABLE `your-table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `package` json DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

现在包裹将是 array/object:

con.query("select * from TEST where id=?", [req.params.id], function (err, results) {
    if (err) throw err;
    console.log(results[0].package.tag); // tag1 using mysql2
    console.log(results[0].package.item); // item1 using mysql2
});

如果你 运行 是低于 5.7 的 MySQL 版本或者你不想使用 JSON 类型,你将需要自己迭代和解析它.

你可以使用这个衬垫:

results = results.map(row => (row.package = JSON.parse(row.package), row));

如果您想知道是否应该将 JSON 存储在关系数据库中,可以在这个问题中进行很好的讨论:

Storing JSON in database vs. having a new column for each key

您可以将 typeCast 函数传递给您的 mysql connection/pool。就我而言,如果可能,我想将所有长文本字段转换为 JSON。在失败的情况下,你仍然会得到原始值。

let auth = {database:'db', password:'pw', user:'u', host:'host.com' };
auth.typeCast = function(field, next) {
    if (field.type == 'BLOB' && field.length == 4294967295) {
        let value = field.string();
        try {
            return JSON.parse(value);
        } catch (e) {
            return value;
        }
    }
    return next();
};
let connection = mysql.createConnection(auth);

您可以使用包 mysql2 而不是 mysql。它会默认解析结果。

这与 Tanner 的回答略有不同,但是,如果您正在使用节点 mysql 库并且您已经使用 MySQL 的 JSON 在数据库中定义了字段数据类型,您可以在最初设置连接时使用“类型转换”,将任何查询返回的任何 JSON 类型的值转换为 JSON 对象:

let connection = mysql.createConnection(
  {typeCast: function (field, next) {
    if (field.type === "JSON") {
      return JSON.parse(field.string());
    } else {
      return next();
    }
  }}
);