如何解决 Sequelize 中出现 Array 类型数据的问题

背景

Sequelize 是 Node.js 中一种流行的 ORM(对象关系映射)工具,它提供了一种方便的方式来操作数据库。在使用 Sequelize 进行开发的过程中,我们有时候会遇到需要存储 Array 类型的数据的情况,但是 Sequelize 并没有直接支持 Array 类型的数据存储。

问题

在 Sequelize 中,我们可以通过定义一个 Model 来映射数据库中的一张表,例如:

const User = sequelize.define('user', {
  name: DataTypes.STRING,
  age: DataTypes.INTEGER
});

在这个 Model 中,我们可以定义表中的字段以及对应的数据类型。但是,当我们需要存储一个数组类型的数据时,该怎么办呢?

下面是一个示例的需求:我们需要存储用户的标签信息,每个用户可以有多个标签,标签以数组的形式存储。我们可以定义一个新的 Model:

const User = sequelize.define('user', {
  name: DataTypes.STRING,
  age: DataTypes.INTEGER,
  tags: ??? // 该怎么定义?
});

解决方案

方案一:使用 JSON 类型

我们可以使用 Sequelize 中提供的 JSON 类型来存储数组类型的数据。在 Model 的定义中,我们可以将 tags 字段定义为 JSON 类型:

const User = sequelize.define('user', {
  name: DataTypes.STRING,
  age: DataTypes.INTEGER,
  tags: DataTypes.JSON
});

在使用时,我们可以将数组类型的数据转换为 JSON 格式进行存储,例如:

const user = await User.create({
  name: '张三',
  age: 18,
  tags: JSON.stringify(['篮球', '足球'])
});

在查询时,我们可以通过 JSON 类型的操作符进行查询,例如:

const users = await User.findAll({
  where: {
    tags: {
      [Op.contains]: ['篮球']
    }
  }
});

方案二:使用自定义类型

如果我们不想使用 JSON 类型来存储数组类型的数据,我们还可以自定义一个类型来存储。在 Sequelize 中,我们可以使用 sequelize.define 方法来定义一个自定义类型,例如:

const ARRAY = (type) => {
  return {
    type: DataTypes.TEXT,
    allowNull: true,
    get: function() {
      const value = this.getDataValue('tags');
      if (value) {
        return value.split(',');
      } else {
        return [];
      }
    },
    set: function(val) {
      if (Array.isArray(val)) {
        this.setDataValue('tags', val.join(','));
      } else {
        this.setDataValue('tags', null);
      }
    }
  };
};

const User = sequelize.define('user', {
  name: DataTypes.STRING,
  age: DataTypes.INTEGER,
  tags: ARRAY(DataTypes.STRING)
});

在这个自定义类型中,我们将 tags 字段定义为 TEXT 类型,然后通过 get 和 set 方法来实现对数组类型数据的存储和查询。在 set 方法中,我们将数组类型的数据转换为字符串类型进行存储,在 get 方法中,我们将字符串类型的数据转换为数组类型进行查询。

在使用时,我们可以直接将数组类型的数据存储到数据库中,例如:

const user = await User.create({
  name: '张三',
  age: 18,
  tags: ['篮球', '足球']
});

在查询时,我们可以直接使用数组类型的操作符进行查询,例如:

const users = await User.findAll({
  where: {
    tags: ['篮球']
  }
});

总结

在使用 Sequelize 进行开发的过程中,我们有时候需要存储数组类型的数据。本文介绍了两种解决方案:使用 JSON 类型和使用自定义类型。在实际开发中,我们可以根据需求选择合适的方案来解决问题。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65c0288badd4f0e0ff9e3155