【问题标题】:MySQL query returns a string as a result of JSON_OBJECT()MySQL 查询返回一个字符串作为 JSON_OBJECT() 的结果
【发布时间】:2017-10-01 03:34:37
【问题描述】:

我写了一个查询,它给我一个表中的帖子,还返回一个关于每个帖子作者的信息:

SELECT post.id, post.text, post.datetime, JSON_OBJECT(
                'username', user.username,
                'firstName', user.firstName,
                'firstName', user.lastName) as author
                FROM post
                INNER JOIN user ON post.authorId = user.id;

但作为响应,author 字段是一个字符串:

author: "{"username": "@", "firstName": null}"
datetime: "2017-05-02T20:23:23.000Z"
id: 10
text: "5555"

我尝试使用CAST 来解决这个问题,但无论如何author 是一个字符串:

CAST(JSON_OBJECT(
    'username', user.username,
    'firstName', user.firstName,
    'firstName', user.lastName) as JSON) as author

为什么会发生这种情况以及如何解决?

更新:

我使用 Node.js 和 Express 从服务器发送数据:

app.get('/posts', (req, res, next) => {
    getPosts().then((posts) => {
        res.setHeader('Content-Type', 'application/json');
        res.send(posts);
    })
    .catch(next);
});

   // ...

getPosts() {
        return new Promise((resolve, reject) => {
            const query = `
            SELECT post.id, post.text, post.datetime, JSON_OBJECT(
                'username', user.username,
                'firstName', user.firstName,
                'firstName', user.lastName) as author
                FROM post
                INNER JOIN user ON post.authorId = user.id;`;
            this.connection.query(query, (err, result) => {
                if(err) {
                    return reject(new Error("An error occured getting the posts: " + err));
                }

                console.log(result) // prints author as a string 

                resolve(result || []);
            });
        });
    }

console.log 的结果:

{
    id: 1,
    text: 'hello, world!',
    datetime: 2017-05-02T15:08:34.000Z,
    author: '{"username": "@", "firstName": null}' 
}

我也尝试在这里将res.send(posts) 更改为res.json(posts),但这并没有帮助。

来自客户端的我的功能是接触服务器以获取帖子:

export const getPosts = () => {
    customFetch(apiUrl + '/posts')
    .then(response => response.json())
    .then(json => json)
};

【问题讨论】:

  • 可能特定于您使用的编程语言。顺便说一句,它是什么?
  • 我使用 javascript
  • 我不是节点专家,但我的理解是它有多种不同的方式连接到 RDBMS,遗憾的是您选择的似乎不支持 json 对象。 JSON 毕竟是最近添加到 mysql 的一些东西
  • 我同意@e4c5,这可能是由于客户端如何处理MySQL返回的json对象。您可能必须在 js 代码中将字符串显式转换为 json。
  • @Shadow 我已经这样做了。我更新了我的帖子并从客户端添加了一个触摸服务器的功能。

标签: javascript mysql json node.js express


【解决方案1】:

我认为 MySQL 返回一个字符串很好,因为 JSON_OBJECT() 函数已经通过生成一个表示格式良好的 JSON 的字符串来完成它的工作。

您可以使用 javascript 将该字符串转换为 JSON 对象

var obj = JSON.parse(yourString);

编辑(关于 JSON 和 Javascript 对象)

首先,如果您不知道,JSON 代表 JavaScript Object Notation:这意味着它是一种表示 JavaScript 对象的文本方式。

从 MySQL 的角度来看,您已经在 SELECT 语句中解决了这个问题,因为查询返回的是一个有效的 JSON。

事实是,数据随后被传输到 Javascript(节点),但对象的 Javascript 内部表示与其文本表示(JSON)不同;这意味着您必须“强制转换”它,以便将字符串转换为对象。

为了避免这种转换,您需要的机制需要 MySQL 知道 Javascript 如何表示对象,然后使用这些知识返回对象的字节码。这称为序列化,恐怕它超出了像 MySQL 这样的 dbms 的用途。

希望这能澄清你的疑虑......

【讨论】:

  • 我这样做response => response.json()。或者你的意思是我必须在我的 json 中寻找每个也可以是 json 的键,并为它们使用JSON.parse
  • 是的,整个响应不会是有效的 JSON,但author 字段肯定会。
  • 好的,我从表中获取数据,迭代数据并使用JSON.parse(post.author)修改每个作者并将其发送给客户端。现在效果很好,但看起来很奇怪。 SELECT内部的问题真的没有办法解决吗?
  • 我编辑了我的答案,很想发表评论:)
【解决方案2】:

将整个事物作为 JSON_OBJECT 返回并对其执行一次 JSON.Parse 怎么样

SELECT JSON_OBJECT("id", post.id, "text", post.text, "datetime", post.datetime, "author", JSON_OBJECT(
            'username', user.username,
            'firstName', user.firstName,
            'firstName', user.lastName))
            FROM post
            INNER JOIN user ON post.authorId = user.id;

这样就不需要循环了

【讨论】:

    【解决方案3】:

    在数据库配置文件中使用 JSON typeCast

      connection: {
        ..
        host: process.env.DB_HOST,
        user: process.env.DB_USER,
        ..
        typeCast: function (field, next) {
          if (field.type == 'JSON') {
            return (JSON.parse(field.string())); 
          }
          return next();
        },
        ..
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-05
      • 2021-09-02
      • 2013-12-29
      • 1970-01-01
      相关资源
      最近更新 更多