localStorage 只能存储字符串类型的数据。如果需要存储对象等复杂数据类型,必须先用 JSON.stringify() 方法将其序列化为字符串,存储后再通过 JSON.parse() 解析还原。如果省略这些必要步骤,数据将无法正确存储或读取。

与 localStorage 不同,IndexedDB 支持存储多种数据类型,包括基本类型(如 boolean、number、string 等)和复杂类型(如 object、array、blob 等)。存储时无需手动格式转换,直接操作即可。

在 IndexedDB 中,数据存储的基本单位是对象仓库(object store)。每个浏览器源(origin)可以包含多个数据库,每个数据库可以拥有多个对象仓库,每个对象仓库则存储多条数据记录。

使用 db.createObjectStore(name, options) 方法可以在数据库中创建对象仓库。其中,name 参数指定仓库名称,options 用于配置仓库属性,主要包括 keyPath(定义键名)和 autoIncrement(设置自动递增键值)。这两种配置的组合会产生四种不同的键类型。

需要注意的是,对象仓库的创建或修改必须在 "upgradeneeded" 事件处理函数中进行,否则会抛出错误。


在 "upgradeneeded" 事件处理函数内创建对象仓库,可以避免此类错误。


为了构建灵活的数据库工具库,对象仓库的名称和配置应支持动态传入。因此,我们对 connect() 函数进行改造,允许用户传递仓库选项数组。

createObjectStores() 函数负责具体的仓库创建逻辑,其实现如下:

测试代码也相应调整,在连接数据库时传入对象仓库配置数组,根据需要创建多个仓库。

然而,当前实现存在一个问题:在数据库版本升级时,没有检查仓库是否已存在,直接尝试创建可能导致重复仓库错误。

为避免该问题,应在创建前使用 db.objectStoreNames.contains(name) 方法检查仓库名是否存在。db.objectStoreNames 是一个包含所有仓库名称的类数组对象。
改造后的对象仓库创建函数如下:

经过优化,版本升级时将仅创建不存在的新仓库,避免重复创建错误。
同步更新测试代码:

错误信息消失,新旧仓库均正常创建。


|