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

Posted

技术标签:

【中文标题】如何从 Nodejs Mysql 获取 JSON 类型作为 JSON 而不是 String【英文标题】:How to get JSON type as JSON instead of String from Nodejs Mysql 【发布时间】:2018-09-26 21:23:37 【问题描述】:

我在 mysql 5.7 中有表说 TEST(id INT, attribute JSON)

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

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"
        
    ]

【问题讨论】:

【参考方案1】:

我想你需要做的就是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));

);

【讨论】:

results 已经是一个数组,这将不起作用。他必须迭代并JSON.parse每个包。 仍然无法工作:P,您需要在每一行 package 上使用 JSON.parse。所以results = results.map(row => (row.package = JSON.parse(row.package), row)) 超越了自己,@MarcosCasagrande,ty【参考方案2】:

有没有办法将上述结果中的包裹项获取为 JSON 对象而不是字符串而不迭代数组并执行 JSON.parse 将字符串转换为 JSON?

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

请记住,mysql 包不支持它,但 mysql2 支持。

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

现在包将是一个数组/对象:

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

如果您运行的 MySQL 版本低于 5.7,或者您不想使用 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

【讨论】:

感谢马科斯的回复。我使用 JSON 作为我的问题中提到的数据类型。默认情况下,mysql 查询节点模块的结果会自动转换为 STRING,即我不能直接作为 JSON 对象访问。我需要做 JSON.parse(results[0].package)... @Deepan 检查我更新的答案,你必须使用mysql2 包!而且您没有提到您使用的是 JSON 数据类型。 谢谢马库斯。 mysql2 包完成了这项工作。我用mysql2节点包替换了mysql。 关键是mysql2包。谢谢!【参考方案3】:

您可以将 typeCast 函数传递给您的 mysql 连接/池。就我而言,如果可能,我想将所有长文本字段转换为 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);

【讨论】:

【参考方案4】:

您可以使用包mysql2 代替mysql。它会默认解析结果。

【讨论】:

【参考方案5】:

这与 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();
    
  
);

【讨论】:

以上是关于如何从 Nodejs Mysql 获取 JSON 类型作为 JSON 而不是 String的主要内容,如果未能解决你的问题,请参考以下文章

如何创建从 nodejs mysql 模块获取的正确 json 类型数据?

如何从sql中获取nodejs的数据并返回json?

如何使用 nodeJS 从 axios 库中获取有效的 JSON 响应

从 Nodejs 中的 mySQL 获取数据时如何从 Async/await 函数获取返回值

当我直接从 MySQL 获取时,NodeJS 响应 MySQL 时区不同

当我直接从 MySQL 获取时,NodeJS 响应 MySQL 时区不同