简介

这篇文章是NestJS我在通过框架开发的过程中所领悟到的know-how的记录。可能有比我建议的更好的方法。建议总是受欢迎的:)

NestJS- 框架TypeORM通过库管理数据库。这篇文章TypeORM介绍了如何在 MySQL DB 中存储 JSON 数组。

当我们在数据库列中保存“数组”时?

在 DB 列中存储数组类型比您想象的更频繁。

外键关系(OneToMany/ManyToOne)

Person Email Consider实体和实体存在的情况。此时,由于一个人可以拥有多封电子邮件,因此两者之间的关系是“OneToMany/ManyToOne”。 MySQL 表的存储方式如下。

+----+--------------------+--------------+
| id | person             | email_id(fk) |
+----+--------------------+--------------+
| 1  | Tom                | 1            |
| 2  | Evans              | 2, 3         |
+----+--------------------+--------------+

+----+------------------+----------------+
| id | email            | person_id(fk)  |
+----+------------------+----------------+
| 1  | tom@mail.com     | 1              |
| 2  | evans@mail.com   | 2              |
| 3  | evans@univ.ac.kr | 2              |
+----+------------------+----------------+

进入全屏模式 退出全屏模式

看两张表,每张表都有一个外键,分别叫email_idperson_idPersonEvans的情况下,它有两封邮件,所以它有一个email_id的数组。

即在 OneToMany/ManyToOne 关系下可以找到fk_idArray。

simple-array

即使不是外键,也可以将数组存储在 MySQL 列中。TypeORM帮助simple-array你通过MySQL存储简单的数组。

@Column('simple-array')
num_arr: number[];

@Column('simple-array')
str_arr: string[];

进入全屏模式 退出全屏模式

但是,如果以simple-array的方式存储string[],就会出现一些问题。这将在后面更详细地处理。

如何保存JSON数组?

到目前为止,我们已经研究了在 MySQL 中存储数组的情况。现在让我们看看如何在 MySQL 中存储 JSON 数组。

simple-array来试试吧!

@Column('simple-array')
json_arr: JSON[];

进入全屏模式 退出全屏模式

@Column,simple-array和之前一样以数组的形式声明。这可以保存吗?不!在这种情况下,会发生错误。让我们看看错误信息。

DataTypeNotSupportedError: Data type "Array" in "example.json_arr" is not supported by "mysql" database.

进入全屏模式 退出全屏模式

??前面我们研究了 MySQL 使用数组的情况。数组,但现在错误消息说 MySQL 不支持该类型。

错误信息是正确的。 MySQL Array 不支持类型。它只是给我们以某种方式支持数组的感觉!!

simple-array来试试吧! -string[]版本

让我们看看如何规避当前的问题。我们的目的仍然是在 MySQL 中存储 JSON 数组。但是JSON[]的形式是不可能的,所以string[]让我们绕过我们之前看的方法。

@Column('simple-array')
json_arr: string[];

进入全屏模式 退出全屏模式

在javascript中,可以通过JSON.stringify()的形式序列化一个名为.我们的计划如下——

  1. API 接收 JSON 数组形式的输入。

2.遍历接收到的JSON数组,适用于所有JSONJSON.stringify()进行序列化

3.string[]另存为 MySQL

4.Get每当string[]有请求进来时,将存储为JSON.parse()的字符串数组中的字符串解析并返回为

如果这样做,您可以将 JSON 数组转换为字符串数组并将其存储在 DB 中而不会出现错误消息。

但...

字符串[] 版本问题

对于我们这些存储 JSON 的人来说,这种方法也有问题。

假设您有一个这样的 JSON 数组:

[{name: 'Baker', job: 'musician'}, {name: 'Euler', job: 'mathematician'}]

进入全屏模式 退出全屏模式

JSON.stringify()如果我们将其更改为

["{name: 'Baker', job: 'musician'}", "{name: 'Euler', job: 'mathematician'}"]

进入全屏模式 退出全屏模式

变成

保存到数据库工作正常。但是获取,如果您使用...检查存储在数据库中的内容...

["{name: 'Baker'", 
 "job: 'musician'}",
 "{name: 'Euler'", 
 "job: 'mathematician'}"]

进入全屏模式 退出全屏模式

它具有以下奇异的形式......!

原因是......

MySQL伪数组

我们认为 MySQL 支持数字数组或字符串数组,即使无法存储 JSON 数组。但是......那是TypeORM的一招!!

实际上 MySQLArray根本不支持类型! (已经通过错误消息确认。)那么simple-array,我们如何使用属性保存它?

simple-array将所有数组存储为字符串。如果是数字数组,则为"1, 2, 3",如果是字符串数组,则为"Bill, John, Baker"。因此,即使在字符串中间插入逗号(,),也会像这样存储在DB中。

"'In other words, please be true', 'In other words, I love you'"

进入全屏模式 退出全屏模式

也就是说,即使是字符串数组,DB中也只存储了一个字符串。并根据逗号 (,) 解析声明为TypeORM的列的信息。simple-array因此,即使您最初保存了 2 个字符串,如果您读取 DB 值,您也会得到 4 个字符串。

实际上 MySQL 并没有什么问题。TypeORM可能是 MySQL 的simple-array方法,尤其是在 中,导致了这个问题。在其他数据库中,它可能不会像这样存储为单个字符串。 2 在 MySQL 中,这是......ᅲᅲ

在 JSON 的情况下,逗号 (,) 必须出现以列出对象,但在一般字符串中,逗号很少见。所以TypeORM开发者可能没有注意到。然而,即使是这样一个小错误也可能成为一个很大的障碍或导致开发中的错误。 (为此我损失了半天......)

[解决方案] 保存为字符串即可!

通过几次试验和错误,simple-array我确认了TypeORM如何在MySQL中存储数组......

所以让我们用它来重新组织我们的代码。

@Column()
json_arr: string;

进入全屏模式 退出全屏模式

列只是string设置为 .

JSON 数组JSON.stringify()中的每个 JSON 都被序列化为一个函数。然后,将它们JSON.parse()转换为可能的形式并存储。

// save JSON array into MySQL DB
saveJSONArray(json_arr: JSON[]) {
  let jsonArr_string = "[";
  for(let i=0; i < json_arr.lenght; i++){
    jsonArr_string += JSON.stringify(json_arr[i]);
    if(i < json_arr.lenght-1){
      jsonArr_string += ",";
    }
  }
  jsonArr_string += "]";
  this.yourRepository.save({ json_arr: jsonArr_string });
}

// load JSON array from MySQL DB
async findJSONArray(): Promise<YourEntry[]> {
  const entry_arr = await this.yourRepository.find();
  for(let i=0; i < entry_arr.lenght; i++){
    entry_arr[i].json_arr = JSON.parse(entry_arr[i].json_arr);
  }
  return entry_arr;
}

进入全屏模式 退出全屏模式

我认为最好的方法是将其设置为json_arr: string,将 DB 值解析为 ,并将其作为 JSON 返回。JSON.parse()(当然,有人可能已经找到了比这更好的方法并好好利用它!)

Logo

华为、百度、京东云现已入驻,来创建你的专属开发者社区吧!

更多推荐