- IndexedDB 教程
- IndexedDB - 首页
- IndexedDB - 简介
- IndexedDB - 安装
- IndexedDB - 连接
- IndexedDB - 对象存储
- IndexedDB - 创建数据
- IndexedDB - 读取数据
- IndexedDB - 更新数据
- IndexedDB - 删除数据
- 使用 getAll() 函数
- IndexedDB - 索引
- IndexedDB - 范围
- IndexedDB - 事务
- IndexedDB - 错误处理
- IndexedDB - 搜索
- IndexedDB - 游标
- IndexedDB - Promise 包装器
- IndexedDB - ECMAScript 绑定
- IndexedDB 有用资源
- IndexedDB 快速指南
- IndexedDB - 有用资源
- IndexedDB - 讨论
IndexedDB 快速指南
IndexedDB - 简介
数据库管理系统提供了一种存储和检索数据的机制。其中,最常用的数据库类型包括:
- 层次数据库
- 网络数据库
- 面向对象数据库
- 关系数据库
- NoSQL 数据库
NoSQL 数据库
NoSQL 数据库(有时称为 Not Only SQL)是一种数据库,它提供了一种存储和检索数据的机制,不同于关系数据库中使用的表格关系。这些数据库是无模式的,支持轻松复制,具有简单的 API,最终一致,并且可以处理海量数据(大数据)。
NoSQL 数据库也有不同的类型,例如:
- 文档数据库。
键值存储。
列式数据库。
图数据库。
什么是 IndexedDB
Indexed Database 是一种 NoSQL 数据库或非关系型结构化查询语言数据库。它是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。但是,与使用固定列表的基于 SQL 的 RDBMS 不同,IndexedDB 是一个基于 JavaScript 的面向对象数据库。
当我们需要在服务器端存储大量数据并且速度比本地存储更快时,可以使用它。因为它将数据存储在浏览器中,所以它也可以在线和离线使用。使用它,您可以创建一个(具有丰富的查询功能)能够在线和离线运行的 Web 应用程序。
IndexedDB 的关键特性
以下是 IndexedDB 数据库的关键特性:
IndexedDB 是一个 NoSQL 数据库,它存储键值对。它可以通过键或多种键类型存储几乎任何类型的键值。
如前所述,IndexedDB 遵循事务型数据库模型 - 事务是围绕操作或操作组的包装类,以便维护数据完整性。您不希望数据被更改或丢失,因此如果事务失败,则会回滚。
IndexedDB 不使用结构化查询语言 - 由于 IndexedDB 使用 NoSQL 数据库,因此它不使用 SQL,而是使用索引上的查询通过游标或getAll() 方法来迭代不同的集合。
IndexedDB 使用大量请求 - 请求是接收 DOM 事件成功或失败的对象(DOM - HTML DOM 事件允许 JavaScript 在 HTML 文档中的元素上注册不同的事件处理程序)。DOM 事件是成功或错误,它有一个 target 属性,指示请求的流程。
成功事件无法取消,但错误事件可以取消。IndexedDB 中有很多请求,例如 onsuccess、onerror 和addEventListener()、removeEventListener()。为了了解请求的状态,我们还有 readyState、result 和错误代码属性。
IndexedDB 需要遵循同源策略 - 原点是编写脚本的文档的 URL,每个原点在其下有一些数据库,每个数据库都有其名称来标识原点。对 IndexedDB 实施的安全边界阻止应用程序访问不同原点的数据。
例如,如果我们采用一个 URL 并采用其不同的子目录,它可以检索数据;但是,如果我们将位置更改为端口 8080 并尝试从常规 URL 和更改的端口检索数据,则无法检索数据。
术语
以下是您在继续学习之前应该了解的 IndexedDB 中各种重要的术语:
数据库 - 在 IndexedDB 中,数据库是最高级别,它包含包含数据的对象存储。
对象存储 - 对象存储是 IndexedDB 的数据存储实体。可以将其视为 RDBMS 中的表,我们根据要存储的数据类型(例如:id、名称、学号等)存储数据。
事务 - 对于任何数据库操作,我们执行以下过程。
- 获取数据库对象
- 在数据库上打开事务
- 在事务上打开对象存储,然后对对象存储进行操作。
基本上,事务是一个连接到每个数据库的包装函数,它确保数据完整性,这样如果事务被取消或发生任何错误,它将回调到事务尚未开始的地方。
索引 - 将对象存储视为一个表,我们使用索引从表中检索单个属性的数据。例如:名称、年龄等。
游标 - 在数据库中,如果我们需要遍历对象存储中的多个记录,我们使用游标。
IndexedDB 的支持
IndexedDB 是浏览器中的数据库,因此我们需要检查当前/现有浏览器是否支持它。为此,请将以下代码粘贴到文本编辑器中,将其另存为test.html并在浏览器中运行它。
const indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB; if (!indexedDB) { document.write("IndexedDB could not be found in this browser."); } const request = indexedDB.open("MyDatabase", 1);
如果您的浏览器支持 IndexedDB,则此程序将成功执行,并且将创建一个数据库。
IndexedDB - 安装
Visual Studio Code 是一个重新定义和优化用于构建和调试现代 Web 和云应用程序的代码编辑器。
您可以从其官方网站下载 Visual Studio Code - https://vscode.js.cn
根据您的 PC 配置和操作系统选择您想要的版本。
下载完成后,您可以直接将其安装到您的计算机上。
在 Windows 上安装 Visual Studio Code 安装程序
首先,如上所述下载适用于 Windows 的 Visual Studio Code 安装程序:
- 下载完成后,运行安装程序。
- 然后,接受协议并单击下一步。
- 现在,单击“创建桌面图标”,以便可以从桌面上访问它,然后单击下一步。
- 然后,单击安装按钮。
最后,安装完成后,单击完成按钮,Visual Studio Code 将打开。
- 现在 Visual Studio Code 已成功安装在您的设备上,开始在此代码编辑器中编写代码。
下载、安装和创建 Node.js 项目(可选)
现在安装 Visual Studio Code 后,我们需要安装 Node.js
下载 Node.JS
您可以从其官方网站下载 Node.js,网址为 https://node.org.cn/en/。
根据您的计算机配置选择您选择的版本。
LTS 版本是首选版本,因为它是一个更稳定的版本,它代表长期支持。
安装 Node.js
按照以下步骤在您的系统中安装 Node.js:
步骤 1 - 现在 Node.js 已打开。您会看到此窗口弹出,单击下一步。
步骤 2 - 您将被重定向到“最终用户许可协议”窗口。接受协议并单击下一步。
步骤 3 - 在下一个窗口中,您需要选择“目标文件夹”。更改现有文件夹,或使用提到的默认文件夹,然后单击下一步。
步骤 4 - 在“自定义安装”和“原生模块工具”窗口中单击下一步。
步骤 5 - 现在,设置已准备好,单击安装以安装所选模块。
IndexedDB - 连接
数据库是有组织的结构化数据集合,存储在计算机系统中。要对数据执行操作,我们需要连接到数据库。在本章中,我们将讨论如何创建/连接到数据库、打开数据库和删除数据库。
创建数据库 - 您可以使用open() 函数在 IndexedDB 中创建数据库。以下是此函数的语法。
let openRequest = indexedDB.open(name, version);
其中,
- name 是您需要创建的数据库的名称。
- version 是要创建的数据库的版本。此参数的默认值为 1。如果您省略此值,则版本被认为是 1。
传递给此函数的版本值不应小于当前版本(IndexedDB)。如果数据库创建成功,此函数返回 1;如果失败,则返回 0。
示例
以下是如何在 IndexedDB 中创建数据库的示例
<!DOCTYPE html> <html lang="en"> <head> <title>Indexed db</title> </head> <body> <script> //Creating a database const request = indexedDB.open("myDatabase", 1); if(indexedDB){ document.write("Database Created......"); } </script> </body> </html>
输出
如果将上述代码保存在“test.html”文件中并运行它,则浏览器上将显示以下消息:
Database Created......
验证
由于 IndexedDB 是浏览器的内置数据库,因此您可以在浏览器本身中观察创建的数据库。
右键单击结果页面,单击检查元素并选择应用程序选项卡。如果展开它,您可以在那里看到 IndexedDB 数据库,您可以看到如下所示的已创建数据库文件:
生成处理程序
事件是在 HTML 元素上执行的操作。使用 JavaScript,我们可以处理这些事件。从现在开始,我们使用 JavaScript 处理程序(为了更清楚起见)。
如果请求成功,我们使用onsuccess 事件。
request.onerror = event => { // Do something (ex: document.write("error"); };
如果请求失败,我们使用onerror 事件。
request.onsuccess = event => { // Do something (ex : document.write("success"); };
当您创建数据库或增加现有数据库的版本号时,我们使用onupgradeneeded 事件。
request.onupgradeneeded = event => { var db = event.target.result; };
示例
以下示例显示消息“数据库创建成功”。如果数据库创建成功。在这里,我们使用onsuccess 和onerror 处理程序来显示这些消息。
<!DOCTYPE html> <html lang="en"> <head> <title>Handlers</title> </head> <body> <script> const request = indexedDB.open("DATABASE", 1); request.onsuccess = function (){ document.write("Database created successfully...") } request.onerror = function(){ document.write("database creation error"); } request.onupgradeneeded = function(event){ var db = event.target.result; } </script> </body> </html>
输出
如果将上述代码保存在“test.html”文件中并运行它,则浏览器上将显示以下消息:
Database created successfully...
连接到现有数据库
要与 IndexedDB 交互,我们使用 JavaScript。我们在 JavaScript 中编写的代码不会直接与数据库交互。我们需要使用连接对象连接到数据库才能操作数据库的对象。
直接打开数据库会创建一个连接。可以有多个连接到数据库。当最初创建连接时,它处于打开状态。
您可以使用open() 函数(我们用来创建数据库的函数)连接到 IndexedDB 数据库。
语法
以下是连接到现有数据库的语法。
let openRequest = indexedDB.open(name, version);
示例
下面给出了一个使用连接对象与现有数据库交互的 JavaScript 示例:
<!DOCTYPE html> <html lang="en"> <head> <title>OPENING A DATABASE</title> </head> <body> <script> const request = indexedDB.open("DATABASE", 1); request.onsuccess = function (){ document.write("<br> Database created successfully") } const requestone = indexedDB.open("Database1",2); requestone.onsuccess = function(){ document.write("<br> Database created successfully"); } const requesttwo = indexedDB.open("DATABASE",1); requesttwo.onsuccess = function(){ document.write("<br> Database opened successfully"); } </script> </body> </html>
输出
上述程序在浏览器上打印以下输出:
Database created successfully Database opened successfully Database created successfully
如果请求成功,则将调用名为 onsuccess 的事件。
另一种在浏览器中检查数据库的方法
除了检查元素之外,还有一种方法可以在浏览器中检查 IndexedDB 数据库。
在右上角,将有一个自定义和控制按钮,单击它。
在列表中选择更多工具选项,然后选择开发者工具。
在下一页中选择应用程序选项卡,您可以在其中看到 IndexedDB 数据库。
删除数据库
如果存在任何不需要的数据库或其不必要地占用空间,我们可以将其删除。要删除数据库,可以使用deleteDatabase()函数。
以下是deleteDatabase()函数的语法:
let deleteRequest = indexedDB.deleteDatabase(name)
这里,name参数是要删除的数据库的名称。
示例
以下示例创建一个名为TestDatabase的数据库,并使用deleteDatabase()函数将其删除。
<!DOCTYPE html> <html lang="en"> <head> <title>Indexed db</title> </head> <body> <script> const request = indexedDB.open("TestDatabase", 1); request.onsuccess = function () { document.write("Database Created Successfully"); }; var req = indexedDB.deleteDatabase("TestDatabase"); req.onsuccess = function () { document.write("Database Deleted Successfully"); }; req.onerror = function () { document.write("Couldn't delete the database"); }; </script> </body> </html>
直接从浏览器删除数据库
创建数据库后,可以直接从浏览器中删除它。为此,请按照以下步骤操作:
步骤1 - 使用以下一种方法打开可以在浏览器中查看 IndexedDB 数据库(存储)的页面
检查选项 - 右键点击 → 检查 → 应用程序 或,
开发者工具 - 自定义和控制选项 → 更多工具 → 开发者工具 → 应用程序
步骤2 - 如果展开IndexedDB存储,您可以看到如下所示创建的数据库列表。
步骤3 - 点击要删除的数据库。在右侧,您将找到删除数据库按钮。如果单击它,则将删除此数据库。
关闭数据库
要关闭数据库,我们需要使用函数IDBDatabase.close()
语法
IDBDatabase.close();
IDBDatabase 接口的close()方法立即返回并关闭连接。
在所有事务完成之前,连接不会关闭,但是,不能为此连接创建新事务,如果关闭操作正在进行中,则方法将抛出异常。
IndexedDB - 对象存储
对象存储是 IndexedDB 的数据存储。数据存储在此处。一个数据库可以有多个对象存储。可以将其视为 RDBMS 中的表,我们根据要存储的数据类型存储数据。
为确保数据库完整性,只能使用回调函数idb.open()创建和删除对象存储。它包含一个名为createObjectStore()的方法,用于创建对象存储。
创建对象存储
您可以使用createObjectStore()方法创建对象存储。以下是此方法的语法:
IDBDatabase.createObjectStore(name); Or, IDBDatabase.createObjectStore(name, options);
其中,
- name是对象存储的名称。
- options对象允许我们定义各种配置属性。
示例
以下示例创建一个新的数据库并在其中创建一个对象存储:
<!DOCTYPE html> <html lang="en"> <head> <title>Creating Object Store</title> </head> <body> <script> var request = indexedDB.open("myDatabase", 2); request.onupgradeneeded = event => { var db = event.target.result; var objectStore = db.createObjectStore("customers"); document.write("Object store Created Successfully..."); }; </script> </body> </html>
输出
执行后,上述程序会在浏览器上显示以下消息。
Object store Created Successfully...
验证
如果成功执行上述程序,展开“myDatabase”,您可以看到新创建的对象存储。
定义主键
类似于 RDBMS,我们需要主键来唯一地定义对象存储中的某些数据。可以使用键路径或键生成器两种方式来完成。
键路径和键生成器
键路径是一个始终存在且包含唯一值的属性。例如,我们可以选择一个唯一值,例如电子邮件地址。
键生成器为添加到对象存储的每个对象创建一个唯一值。默认情况下,如果我们不提及键生成器,它就会出现。例如,自动递增。
语法
以下是创建对象存储键路径的语法。
var objectStore = db.createObjectStore("ObjectStoreName", { keyPath: "primary key, autoincrement/autoDecrement : true" });
示例
在下面的示例中,我们使用 JavaScript 为对象存储创建一个键路径:
<!DOCTYPE html> <html lang="en"> <head> <title>keypath</title> </head> <body> <script> var request = indexedDB.open("myDtabase", 2); request.onupgradeneeded = event => { var db = event.target.result; var objectStore = db.createObjectStore("customers",{keyPath:"id", autoIncrement:true}); document.write("Object store Created Successfully..."); }; </script> </body> </html>
输出
执行上述示例后,它将在浏览器上显示以下文本:
Object store Created Successfully...
验证
如果成功执行上述程序,展开“myDatabase”,您可以看到新创建的对象存储,如果单击它,您可以观察到为“id”创建了键路径。
创建新的对象存储时,它们会像上面一样在 IndexedDB 文件夹中提到。
您可以同时使用键路径和键生成器。如果数据始终唯一,我们可以使用键路径;如果值发生更改,可以使用键生成器;如果要为每个值更改值,但要提供唯一表示存储的值,则可以使用两者。
定义索引
索引是一种对象存储。它们用于从由指定属性存储的引用对象检索数据。索引使用指定的属性作为其键路径,而不是引用存储的主键。
要创建索引,需要在对象存储实例上调用createIndex()方法。
语法
以下是createIndex()方法的语法:
var myIDBIndex = objectStore.createIndex(indexName, keyPath); var myIDBIndex = objectStore.createIndex(indexName, keyPath, Parameters);
其中,
indexName是创建的索引的名称。
Keypath是在创建对象存储时的主键定义
最后一个参数的值可以是unique或multi-entry
如果您“传递 unique: true”。索引不允许单个键出现重复值。
如果您传递“multi-entry: true”。当 keyPath 解析为数组时,索引将为每个数组元素添加一个条目。如果为 false,它将添加一个包含数组的单个条目。
示例
以下 JavaScript 示例演示如何创建索引。
<!DOCTYPE html> <html lang="en"> <head> <title>OPENING A DATABASE</title> </head> <body> <script> const dbName = "myDB"; const studentdata = [ {name : "jason" , rollno: "160218737028" , branch : "IT"}, {name : "lokesh" , rollno: "160218735020" , branch : "CSE"}, {name : "tarun" , rollno: "160218733057" , branch : "EEE"}, {name : "pranith" , rollno: "160218737029" , branch : "IT"} ]; var request = indexedDB.open("myDB", 2); request.onupgradeneeded = event => { var db = event.target.result; var objectStore = db.createObjectStore("student",{ keyPath :"rollno" }); objectStore.createIndex("name", "name", { unique: false }); objectStore.createIndex("branch", "branch", { unique: false }); objectStore.transaction.oncomplete = event => { var objectStore = db.transaction("student", "readwrite").objectStore("student"); studentdata.forEach(function(student) { objectStore.add(student); }); }; }; </script> </body> </html>
输出
如果您转到并验证 IndexedDB 数据库myDB的内容并展开它,您可以看到创建的表如下:
如果您单击名称和学生值,您可以看到索引值如下:
名称索引
# | 键(键路径:“name”) | 主键(键路径:“rollno”) | 值 |
---|---|---|---|
0 | "jason" | "160218737028" | {name: 'jason', rollno: '160218737028', branch 1. branch: "IT" 2. name: "jason" 3. rollno: "160218737028" |
1 | "lokesh" | "160218735020" | {name: 'lokesh', rollno: '160218735020', branch: 'CSE'} 1. branch: "CSE" 2. name: "lokesh" 3. rollno: "160218735020" |
2 | "pranith" | "160218737029" | {name: 'pranith', rollno: '160218737029', branch: 'IT'} 1. branch: "IT" 2. name: "pranith" 3. rollno: "160218737029" |
3 | "tarun" | "160218733057" | {name: 'tarun', rollno: '160218733057', branch: 'EEE'} 1. branch: "EEE" 2. name: "tarun" 3. rollno: "160218733057" |
分支索引
# | 键(键路径:“branch”) | 主键(键路径:“rollno”) | 值 |
---|---|---|---|
0 | "CSE" | "160218735020" | {name:'lokesh', rollno:'160218735020', branch: 'CSE'} 1. branch: "CSE" 2. name: "lokesh" 3. rollno: "160218735020" |
1 | "EEE" | "160218733057" | {name:'tarun', rollno: '160218733057', branch: 'EEE'} 1. branch: "EEE" 2. name: "tarun" 3. rollno: "160218733057" |
2 | "IT" | "160218737028" | {name:'jason', rollno: '160218737028', branch: 'IT'} 1. branch: "IT" 2. name: "jason" 3. rollno: "160218737028" |
3 | "IT" | "160218737029" | {name:'pranith', rollno: '160218737029', branch: 'IT'} 1. branch: "IT" 2. name: "pranith" 3. rollno: "160218737029" |
删除对象存储
对象存储类似于数据库中的表,当不需要表时,我们会将其删除。类似地,如果不再使用对象存储,您可以将其删除。要删除对象存储,需要调用deleteObjectStore()函数。
语法
以下是deleteObjectStore()函数的语法:
db.deleteObjectStore("store_name");
其中,store_name是要删除的对象存储的名称。
示例
让我们来看一个 JavaScript 示例,该示例删除不再需要的对象存储:
<!DOCTYPE html> <html lang="en"> <head> <title>OPENING A DATABASE</title> </head> <body> <script> const dbName = "Database"; var request = indexedDB.open("Database", 2); request.onupgradeneeded = event => { var db = event.target.result; var objectStore = db.createObjectStore("student",{ keyPath :"rollno" } ); var objstore = db.createObjectStore("college",{autoIncrement : true}); db.deleteObjectStore("college"); }; </script> </body> </html>
输出
在浏览器中删除 IndexedDB 文件夹中的对象存储之前和之后。
Database College − object store Student − object store Name − index Branch − index Database Student − object store Name − index Branch − index
IndexedDB - 创建数据
在创建数据之前,我们需要了解数据是如何传输的。IndexedDB 打开事务,其每个数据操作都在每个事务内执行。每个操作都有四个步骤:
- 获取数据库对象
- 在数据库上打开事务
- 在事务上打开对象存储
- 对对象存储进行操作
IndexedDB 中的操作:
- 创建
- 读取
- 更新
- 删除
首先,要在我们的数据库中执行任何操作,我们需要打开一个事务。打开事务后,我们需要获取所需的对象存储。这些对象存储仅根据创建事务时提到的要求提供。然后,可以稍后添加任何所需的数据。
函数用于执行给定的操作(如果有)。例如,我们使用 add() 函数将数据添加到数据库或添加新条目。
语法
以下是将数据创建到数据库中的语法:
ar request = objectStore.add(data);
我们可以使用add()或put()函数将数据添加到对象存储中。
示例
在下面的示例中,我们使用 JavaScript 中的 add() 方法将数据插入对象存储中:
<!DOCTYPE html> <html lang="en"> <head> <title>creating data</title> </head> <body> <script> const dbName = "Database"; var request = indexedDB.open("Database", 2); request.onupgradeneeded = event => { var db = event.target.result; var objectStore = db.createObjectStore("student",{ keyPath :"rollno" } ); }; request.onsuccess = event => { document.write("Database opened successfully"); var db = event.target.result; var transaction = db.transaction("student", "readwrite"); var objectStore = transaction.objectStore("student"); objectStore.add({ rollno: 160218737028, name: "jason", branch: "IT" }); objectStore.add({ rollno: 160218733028, name: "tarun", branch: "EEE" }); objectStore.add({ rollno: 160218732028, name: "lokesh", branch: "CSE" }); objectStore.add({ rollno: 160218737025, name: "abdul", branch: "IT" }); objectStore.add({ rollno: 160218736055, name: "palli", branch: "MECH" }); } transaction.oncomplete = function () { db.close(); }; </script> </body> </html>
输出
0 160218732028 {rollno: 160218732028, name: 'lokesh', branch: 'CSE'} 1 160218733028 {rollno: 160218733028, name: 'tarun', branch: 'EEE'} 2 160218736055 {rollno: 160218736055, name: 'palli', branch: 'CSE'} 3 160218737025 {rollno: 160218737025, name: 'abdul', branch: 'IT'} 4 160218737028 {rollno: 160218737028, name: 'jason', branch: 'IT'}
IndexedDB - 读取数据
我们将数据输入数据库,我们需要调用数据以查看更改,以及用于各种其他目的。
我们必须在对象存储上调用get()方法来读取此数据。get 方法获取要从存储中检索的对象的主键。
语法
var request = objectstore.get(data);
在这里,我们请求对象存储使用 get() 函数获取数据。
示例
以下示例是请求对象存储获取数据的实现:
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> </head> <body> <script> const request = indexedDB.open("botdatabase",1); request.onupgradeneeded = function(){ const db = request.result; const store = db.createObjectStore("bots",{ keyPath: "id"}); } request.onsuccess = function(){ document.write("database opened successfully"); const db = request.result; const transaction=db.transaction("bots","readwrite"); const store = transaction.objectStore("bots"); store.add({id: 1, name: "jason",branch: "IT"}); store.add({id: 2, name: "praneeth",branch: "CSE"}); store.add({id: 3, name: "palli",branch: "EEE"}); store.add({id: 4, name: "abdul",branch: "IT"}); const idquery = store.get(4); idquery.onsuccess = function(){ document.write("idquery",idquery.result); } transaction.oncomplete = function(){ db.close; } } </script> </body> </html>
输出
database opened successfully idquery {id: 4, name: 'abdul', branch: 'IT'}
IndexedDB - 更新数据
创建数据后,下一步是对其执行各种操作;因此,我们需要定期更新数据。如果我们将数据错误地输入到数据库中,我们还需要更新数据。在这里,我们必须指定一个读写事务,因为我们要写入数据库,而不仅仅是从数据库读取。
如果我们想修改它或做一个已经存在于数据库中的条目,我们使用put()函数。
语法
var requestUpdate = objectStore.put(data);
我们对发生事务的对象存储使用put()函数,我们需要更新数据。
示例
让我们来看下面的脚本,了解如何使用 put() 函数更新或修改对象存储中的数据:
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> </head> <body> <script> const request = indexedDB.open("botdatabase",1); request.onupgradeneeded = function(){ const db = request.result; const store = db.createObjectStore("bots",{ keyPath: "id"}); } request.onsuccess = function(){ document.write("database opened successfully"); const db = request.result; const transaction=db.transaction("bots","readwrite"); const store = transaction.objectStore("bots"); store.add({id: 1, name: "jason",branch: "IT"}); store.add({id: 2, name: "praneeth",branch: "CSE"}); store.add({id: 3, name: "palli",branch: "EEE"}); store.add({id: 4, name: "abdul",branch: "IT"}); store.put({id: 4, name: "deevana",branch: "CSE"}); const idquery = store.get(4); idquery.onsuccess = function(){ document.write("idquery",idquery.result); } transaction.oncomplete = function(){ db.close; } } </script> </body> </html>
输出
database opened successfully idquery {id: 4, name: 'deevana', branch: 'CSE'} Previously the data stored in id: 4 was Name: abdul Branch : IT But as we updated the entry the values are changed.
IndexedDB - 删除数据
在许多情况下,我们需要从数据库中删除数据;无论是出于存储目的,还是仅仅是为了删除不需要的数据以释放空间。如果我们想从数据库中删除这些不需要的数据,我们可以使用 .delete() 函数
语法
const request = objectStore.delete(data);
我们使用delete()函数删除数据库中不需要的字段。
示例
让我们来看一个删除数据的示例脚本:
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> </head> <body> <script> const request = indexedDB.open("botdatabase",1); request.onupgradeneeded = function(){ const db = request.result; const store = db.createObjectStore("bots",{ keyPath: "id"}); } request.onsuccess = function(){ document.write("database opened successfully"); const db = request.result; const transaction=db.transaction("bots","readwrite"); const store = transaction.objectStore("bots"); store.add({id: 1, name: "jason",branch: "IT"}); store.add({id: 2, name: "praneeth",branch: "CSE"}); store.add({id: 3, name: "palli",branch: "EEE"}); store.add({id: 4, name: "abdul",branch: "IT"}); store.put({id: 4, name: "deevana",branch: "CSE const deletename = store.delete(1); deletename.onsuccess = function(){ document.write("id : 1 has been deleted"); } transaction.oncomplete = function(){ db.close; } } </script> </body> </html>
输出
database opened successfully id : 1 has been deleted
删除 id:1 后的数据库:
0 2 {id: 2, name: 'praneeth', branch: 'CSE'} 1 3 {id: 3, name: 'palli', branch: 'EEE'} 2 4 {id: 4, name: 'deevana', branch: 'CSE'}
IndexedDB - 使用 getAll() 函数
在前面的部分中,我们一次只从存储中检索一个对象。现在我们可以检索对象存储的所有数据或子集。getAll 方法使用 getAll() 函数返回对象存储中的所有对象
语法
ObjectStore.getAll(optionalConstraint);
我们可以直接调用 getAll() 来返回对象存储中存储的所有对象,或者我们可以指定可选约束,例如汽车数据库中的红色汽车
示例
在下面的示例脚本中,我们调用 getAll() 方法一次返回对象存储中存储的所有对象:
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> </head> <body> <script> const request = indexedDB.open("botdatabase",1); request.onupgradeneeded = function(){ const db = request.result; const store = db.createObjectStore("bots",{ keyPath: "id"}); store.createIndex("branch_db",["branch"],{unique: false}); } request.onsuccess = function(){ document.write("database opened successfully"); const db = request.result; const transaction=db.transaction("bots","readwrite"); const store = transaction.objectStore("bots"); const branchIndex = store.index("branch_db"); store.add({id: 1, name: "jason",branch: "IT"}); store.add({id: 2, name: "praneeth",branch: "CSE"}); store.add({id: 3, name: "palli",branch: "EEE"}); store.add({id: 4, name: "abdul",branch: "IT"}); store.put({id: 4, name: "deevana",branch: "CSE"}); const query = branchIndex.getAll(["IT"]); query.onsuccess = function(){ document.write("query",query.result); } transaction.oncomplete = function(){ db.close; } } </script> </body> </html>
输出
database opened successfully query (1) [{...}] arg1:(1) [{...}] 0:{id: 1, name: 'jason', branch: 'IT'} length:1 [[Prototype]]:Array(0) [[Prototype]]:Object
IndexedDB - 索引
索引是一种对象存储,用于从由指定属性存储的引用对象检索数据。即使索引位于引用对象存储内并包含相同的数据,它也使用指定的属性作为其键路径,而不是引用存储的主键。
索引用于定义数据的唯一约束,并在创建对象存储时创建。要创建索引,请在对象存储实例上调用 createIndex 方法:
语法
var myIDBIndex = objectStore.createIndex(indexName, keyPath); var myIDBIndex = objectStore.createIndex(indexName, keyPath, objectParameters);
此方法创建并返回索引对象。该方法创建一个包含以下参数的索引:
索引名称 - 索引的名称。
键路径 - 我们在这里提到主键。
对象参数 - 存在两个对象参数。
唯一 − 不允许添加重复值。
多值条目 − 如果为 true,则当 keyPath 解析为数组时,索引将为索引中的每个数组元素添加一个条目。如果为 false,则将添加一个包含数组的单个条目。
示例
以下示例演示了在对象存储中实现索引的方法:
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> </head> <body> <script> const request = indexedDB.open("botdatabase",1); request.onupgradeneeded = function(){ const db = request.result; const store = db.createObjectStore("bots",{ keyPath: "id"}); store.createIndex("branch_db",["branch"],{unique: false}); } request.onsuccess = function(){ document.write("database opened successfully"); const db = request.result; const transaction=db.transaction("bots","readwrite"); const store = transaction.objectStore("bots"); const branchIndex = store.index("branch_db"); store.add({id: 1, name: "jason",branch: "IT"}); store.add({id: 2, name: "praneeth",branch: "CSE"}); store.add({id: 3, name: "palli",branch: "EEE"}); store.add({id: 4, name: "abdul",branch: "IT"}); store.put({id: 4, name: "deevana",branch: "CSE"}); transaction.oncomplete = function(){ db.close; } } </script> </body> </html>
输出
branchIndex: 1 ['CSE'] 0: "CSE" length: 1 4 {id: 4, name: 'deevana', branch: 'CSE'} branch: "CSE" id: 4 name: "deevana" 2 ['EEE'] 0: "EEE" length: 1 3 {id: 3, name: 'palli', branch: 'EEE'} branch: "EEE" id: 3 name: "palli" 3 ['IT'] 0: "IT" length: 1 1 {id: 1, name: 'jason', branch: 'IT'} branch: "IT" id: 1 name: "jason"
IndexedDB - 范围
当我们不想一次获取所有数据时,我们使用范围。当我们只想获取特定范围内的数据时,我们使用范围。我们使用IDBKeyRange对象定义范围。此对象有4个方法:
- upperBound()
- lowerBound()
- bound()
- only()
语法
IDBKeyRange.lowerBound(indexKey); IDBKeyRange.upperBound(indexKey); IDBKeyRange.bound(lowerIndexKey, upperIndexKey);
以下是各种范围代码的列表:
序号 | 范围代码和描述 |
---|---|
1 | 所有键 ≥ a DBKeyRange.lowerBound(a) |
2 | 所有键 > a IDBKeyRange.lowerBound(a, true) |
3 | 所有键 ≤ b IDBKeyRange.upperBound(b) |
4 | 所有键 < b IDBKeyRange.upperBound(b, true) |
5 | 所有键 ≥ a && ≤ b IDBKeyRange.bound(a, b) |
6 | 所有键 > a && < b IDBKeyRange.bound(a, b, true, true) |
7 | 所有键 > a && ≤ b IDBKeyRange.bound(a, b, true, false) |
8 | 所有键 ≥ a && < b IDBKeyRange.bound(a, b, false, true) |
9 | 键 = c IDBKeyRange.only(c) |
我们通常使用索引来使用范围,在语法中,索引键表示索引的 keypath 值。
示例
以下是使用 get() 和 getAll() 方法检索范围代码的各种示例:
class.get(‘student’) class.getAll(IDBKeyRange.bound(‘science’,’math’) class.getAll(IDBKeyRange.upperbound(‘science’,true) class.getAll() class.getAllKeys(IDBKeyRange.lowerbound(‘student’,true))
HTML 示例
考虑以下 HTML 示例以获取范围代码:
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> </head> <body> <script> const request = indexedDB.open("botdatabase",1); request.onupgradeneeded = function(){ const db = request.result; const store = db.createObjectStore("bots",{ keyPath: "id"}); store.createIndex("branch_db",["branch"],{unique: false}); } request.onsuccess = function(){ document.write("database opened successfully"); const db = request.result; const transaction=db.transaction("bots","readwrite"); const store = transaction.objectStore("bots"); const branchIndex = store.index("branch_db"); store.add({id: 1, name: "jason",branch: "IT"}); store.add({id: 2, name: "praneeth",branch: "CSE"}); store.add({id: 3, name: "palli",branch: "EEE"}); store.add({id: 4, name: "abdul",branch: "IT"}); store.put({id: 4, name: "deevana",branch: "CSE"}); const upperquery =store.getAll(IDBKeyRange.upperBound('2', true)); upperquery.onsuccess = function(){ document.write("upperquery",upperquery.result); } transaction.oncomplete = function(){ db.close; } } </script> </body> </html>
输出
database opened successfully upperquery (4) [{...}, {...}, {...}, {...}] arg1: (4) [{...}, {...}, {...}, {...}] 0: {id: 1, name: 'jason', branch: 'IT'} 1: {id: 2, name: 'praneeth', branch: 'CSE'} 2: {id: 3, name: 'palli', branch: 'EEE'} 3: {id: 4, name: 'deevana', branch: 'CSE'} length: 4 [[Prototype]]: Array(0) [[Prototype]]: Object
IndexedDB - 事务
事务是一组操作,这些操作应该全部成功或全部失败。例如,如果我们通过 UPI 向商家付款并且交易失败,则资金必须退回到发送方的账户。事务保持这种完整性。
以下是打开事务的语法:
db.transaction(store[, type]);
这里的 store 是我们想要进行事务的对象存储。事务的类型有两种:
只读 − 只能读取,默认情况下提供。
读写 − 我们既可以读取也可以写入数据,但不能在对象存储中创建、删除或更改它。
事务生命周期
事务是对象存储之间执行任何操作的连接。每个事务都有一个状态,可以是:
活动 − 当事务首次创建时,或当请求与事务关联时。当事务处于此状态时,可以针对事务发出新的请求。
非活动 − 在其创建后的事件返回控制之后,事务处于此状态。当事务处于此状态时,不能针对事务发出任何请求。
提交中 − 一旦与事务关联的所有请求完成,它就会尝试提交。在提交状态期间,不能发出新的请求。
已完成 − 事务提交或中止后,它处于已完成状态。在已完成状态期间,不能发出新的请求。
事务的生命周期
形成具有作用域和模式的事务。事务的状态最初在其生成时为活动状态。
要开始事务,实现必须排队一个任务。
处理与事务关联的每个请求时,将触发成功或错误事件。发送事件时,事务状态设置为活动状态,允许针对事务发出后续请求。事件分派完成后,事务的状态设置为非活动状态。
可以在完成之前随时取消事务,即使它当前未处于活动状态或尚未开始。
当针对数据库的所有请求都成功时,实现必须尝试提交事务。
当事务提交或中止时,其状态将设置为完成。
事务调度
当可以启动事务时,有一些限制。
当没有读或写事务时:a. 在事务 tx 之前建立;b. 与 tx 具有重叠的作用域;c. 不处于最终状态,只读事务 tx 可以开始。
当没有其他事务时,可以开始读/写事务 tx:
- 在 tx 之前形成,
- 与 tx 具有重叠的作用域,或
- 未处于已完成状态。
升级事务
具有模式“versionchange”的事务是升级事务。
可以使用升级操作创建、重命名和删除数据库中的对象存储和索引。
如果给定大于当前版本的版本,则在打开数据库连接后完成运行升级事务的步骤时,将自动生成升级事务。在此事务在upgradeneeded事件处理程序中处于活动状态。
提交事务
必须完成以下步骤才能提交事务:
- 事务状态首先设置为提交中。
- 等待列表中所有事务请求都已处理。
- 如果发生错误,则中止事务。
- 如果事务是升级事务,则将数据库升级事务的事务连接设置为 NULL。
- 将事务状态更改为完成。
- 触发事务的完整事件
- 如果事务是升级事务,则将请求的事务设置为 null 并发出与事务关联的请求。
语法
transaction.commit()
尝试提交事务。所有挂起的请求都将被允许完成,但不会接受新的请求。
如果挂起的请求失败,则事务将中止。成功请求的成功事件仍将触发,但在事件处理程序中引发异常不会中止事务,调用preventDefault()不会阻止事务中止。
事件处理程序
以下是各种事件处理程序属性:
attribute EventHandler onabort; attribute EventHandler oncomplete; attribute EventHandler onerror;
事务示例
以下是一个简单的 JavaScript 程序,用于演示事务的使用:
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> </head> <body> <script> const request = indexedDB.open("botdatabase",1); request.onupgradeneeded = function(){ const db = request.result; const store = db.createObjectStore("bots",{ keyPath: "id"}); } request.onsuccess = function(){ document.write("database opened successfully"); const db = request.result; const transaction=db.transaction("bots","readwrite"); const store = transaction.objectStore("bots"); store.add({id: 1, name: "jason",branch: "IT"}); store.add({id: 2, name: "praneeth",branch: "CSE"}); store.add({id: 3, name: "palli",branch: "EEE"}); store.add({id: 4, name: "abdul",branch: "IT"}); store.put({id: 4, name: "deevana",branch: "CSE"}); transaction.oncomplete = function(){ document.write("transaction complete"); db.close; }; } </script> </body> </html>
输出
database opened successfully transaction complete
此处仅在创建事务时才能将数据添加到对象存储中,最后在事务完成后,我们关闭数据库。
示例
以下示例显示了事务属性 oncomplete 的用法:
function student(db, names) { let transaction = db.transaction(['names'], 'readwrite'); let store = transaction.objectStore('names'); for (let i = 0; i < messages.length; i++) { store.add({text: names[i]}); } transaction.oncomplete = function() {document.write('transaction complete')}; }
中止事务
要中止事务,请按照以下步骤操作:
撤消对数据库的所有与事务相关的修改。
在升级事务期间,对象存储、索引和版本的更改也会被还原。
完成事务状态。
如果错误不为空,则将事务错误设置为错误。
将请求已处理标志设置为事务请求列表中每个请求的 true。
将请求完成标志设置为 true,并将结果设置为定义。
如果事务是升级事务,则将与事务连接关联的升级事务设置为 null。
创建一个带有 bubbles 属性设置为 true 的中止事务事件。
如果事务是升级事务,则假定请求是事务的打开请求。
IndexedDB - 错误处理
并非我们编写的全部请求都会返回输出。这可能是由于:
- 编写代码时可能出错。
- 如果已超过存储限制。
- 如果事务失败等。
在失败的请求中,事务被取消,所有更改都被还原。但有时我们希望在不还原所有更改的情况下处理失败,为此我们使用request.onerror处理程序。它可以通过调用event.preventDefault()来阻止事务中止。
示例
以下是一个示例,用于演示 IndexedDB 中的错误处理:
<!DOCTYPE html> <html lang="en"> <head> <title>IndexedDB</title> </head> <body> <script> const request = indexedDB.open("DATABASE", 1); request.onsuccess = function (){ document.write("database creation success") } request.onerror = function(event){ document.write("Database not created " + event.target.errorCode); } </script> </body> </html>
输出
Database not created undefined
我们可以使用 db.onerror 处理程序来捕获错误。
db.onerror = function(event) { let request = event.target; document.write("Error is found", request.error); };
当具有相同 ID 的对象已存在时,会发生约束错误。但有时如果任何错误都被完全处理,并且我们不想报告它,我们可以使用event.stopPropagation()在 request.onerror 中停止冒泡。
request.onerror = function(event) { if (request.error.name == "ConstraintError") { document.write("id already exists"); event.preventDefault(); event.stopPropagation(); } }
IndexedDB - 搜索
我们会遇到许多需要在对象存储中搜索值的情况。对象存储在内部排序。可以通过以下方式完成:
- 按键值或键范围搜索。
- 根据其他对象字段搜索。
按键搜索
我们可以使用具有可接受键范围的 IDBKeyRange 对象搜索精确的键值或键值范围。IDBKeyRange 对象具有以下调用:
IDBKeyRange.lowerBound(lower, [open]) 用于 >=lower
IDBKeyRange.upperBound(upper, [open]) 用于 >=upper
IDBKeyRange.bound(lower, upper, [lowerOpen] , [upperOpen]) 在 lower 和 upper 之间
IDBKeyRange.only(key) 如果范围仅包含一个键。
要执行实际搜索,我们使用对象存储上的查询参数。执行这些操作的不同类型的方法是
store.get(query) − 按键或范围搜索存储中的第一个值
store.getAll([query],[count]) − 搜索存储中的所有值,直到达到提到的计数限制。
store.getKey(query) − 搜索满足查询的第一个键。
store.getAllKeys([query],[count]) − 搜索满足查询的所有键,直到完成计数限制。
store.count([query]) − 获取满足查询的键的总数。
示例
在此示例中,我们使用 getAll() 方法检索所有对象,并按其键搜索对象:
class.get(‘student’) class.getAll(IDBKeyRange.bound(‘science’,’math’) class.getAll(IDBKeyRange.upperbound(‘science’,true) class.getAll() class.getAllKeys(IDBKeyRange.lowerbound(‘student’,true))
按字段或索引搜索
要根据其他对象字段进行搜索,我们需要使用索引。索引存储具有所需值的对象的键列表。索引也像对象存储一样在内部排序。
语法
objectStore.createIndex(name, keyPath, [options]);
名称 − 索引名称
keyPath − 将对对象字段的路径进行搜索
选项 − 选项有两种类型
唯一 − 存储中具有唯一值的物体将在 key path 中存在,并且不能创建它们的副本。
多值条目 − 如果 keypath 上的值是数组,则默认情况下,索引将把整个数组视为键,但如果我们使用多值条目,则数组成员将成为索引键。
示例
如果我们想根据价格搜索手机,示例程序如下:
openRequest.onupgradeneeded = function() { let books = db.createObjectStore('phone', {keyPath: 'id'}); let index = books.createIndex('pricephone', 'price'); };
要创建索引,我们需要使用升级所需。
- 索引将跟踪价格字段。
- 如果价格不是唯一的,我们不能设置唯一选项。
- 如果价格不是数组,则多值条目不适用。
示例
在以下示例中,我们创建了一个事务并使用 getAll() 函数检索所有对象。检索后,我们在该事务中搜索对象值。如果找到,则返回对象;否则,返回 false。
let transaction = db.transaction("phones"); let books = transaction.objectStore("phones"); let priceIndex = books.index("price_index"); let request = priceIndex.getAll(7); request.onsuccess = function() { if (request.result !== undefined) { document.write("Phones", request.result); } else { document.write("There are no such phones"); } };
HTML 示例
以下是在对象存储中搜索值的 HTML 脚本实现:
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> </head> <body> <script> const request = indexedDB.open("botdatabase",1); request.onupgradeneeded = function(){ const db = request.result; const store = db.createObjectStore("bots",{ keyPath: "id"}); store.createIndex("branch_db",["branch"],{unique: false}); } request.onsuccess = function(){ document.write("database opened successfully"); const db = request.result; const transaction=db.transaction("bots","readwrite"); const store = transaction.objectStore("bots"); const branchIndex = store.index("branch_db"); store.add({id: 1, name: "jason",branch: "IT"}); store.add({id: 2, name: "praneeth",branch: "CSE"}); store.add({id: 3, name: "palli",branch: "EEE"}); store.add({id: 4, name: "abdul",branch: "IT"}); store.put({id: 4, name: "deevana",branch: "CSE"}); const req = branchIndex.getAll(["CSE"]); req.onsuccess = function(){ if(req.result!==undefined){ document.write("bots",req.result); } else{ document.write("There are no such bots"); } }; transaction.oncomplete = function(){ db.close; } } </script> </body> </html>
输出
database opened successfully bots (2) [{...}, {...}] arg1:(2) [{...}, {...}] 0:{id: 2, name: 'praneeth', branch: 'CSE'} 1:{id: 4, name: 'deevana', branch: 'CSE'} length:2 [[Prototype]]:Array(0) [[Prototype]]:Object
IndexedDB - 游标
在检索数据时,当我们知道要检索哪个键时,我们使用了get()函数,但如果我们想遍历对象存储的所有值,我们可以使用游标。
首先,我们使用 open cursor 函数,然后我们可以向其中添加参数。我们可以在openCursor()函数中插入的参数是:
- 使用键范围限制对象的范围
- 我们想要迭代的方向
以下是游标的语法
语法
ObjectStore.openCursor(optionalKeyRange, optionalDirection);
对于对象存储,我们使用openCursor()
optionalKeyRange − 我们可以限制需要检索的对象数量的范围。
optionalDirection − 我们可以指定我们想要迭代的方向。
示例 1
在此示例中,我们将学习如何使用 JavaScript 打开游标函数:
var objectStore = db.transaction("student").objectStore("student”); objectStore.openCursor().onsuccess = event => { var cursor = event.target.result; if (cursor) { document.write("Name" + cursor.key + cursor.value.name); cursor.continue(); } else { document.write("entries closed"); } };
示例 2
当我们想要检索对象存储中的所有对象并将它们放入数组中时。
var student = []; objectStore.openCursor().onsuccess = event => { var cursor = event.target.result; if (cursor) { student.push(cursor.value); cursor.continue(); } else { document.write(student); } };
示例 3
下面是另一个在 JavaScript 中实现 openCursor() 函数的示例:
var singleKeyRange = IDBKeyRange.only("Jason"); var lowerBoundKeyRange = IDBKeyRange.lowerBound("Praneeth"); var lowerBoundOpenKeyRange = IDBKeyRange.lowerBound("jason", true); var upperBoundOpenKeyRange = IDBKeyRange.upperBound("praneeth", true); var boundKeyRange = IDBKeyRange.bound("jason", "praneeth", false, true); index.openCursor(boundKeyRange).onsuccess = event => { var cursor = event.target.result; if (cursor) { cursor.continue(); } };
或者如果我们想指定方向:
objectStore.openCursor(boundKeyRange, "prev").onsuccess = event => { var cursor = event.target.result; if (cursor) { cursor.continue(); } };
HTML 示例
实现游标函数用法的 HTML 脚本如下:
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> </head> <body> <script> const request = indexedDB.open("botdatabase",1); request.onupgradeneeded = function(){ const db = request.result; const store = db.createObjectStore("bots",{ keyPath: "id"}); store.createIndex("branch_db",["branch"],{unique: false}); } request.onsuccess = function(){ document.write("database opened successfully"); const db = request.result; const transaction=db.transaction("bots","readwrite"); const store = transaction.objectStore("bots"); const branchIndex = store.index("branch_db"); store.add({id: 1, name: "jason",branch: "IT"}); store.add({id: 2, name: "praneeth",branch: "CSE"}); store.add({id: 3, name: "palli",branch: "EEE"}); store.add({id: 4, name: "abdul",branch: "IT"}); store.put({id: 4, name: "deevana",branch: "CSE"}); const req = store.openCursor(); req.onsuccess = function(){ const cursor = req.result; if(cursor){ const key = cursor.key; const value = cursor.value; document.write(key,value); cursor.continue(); } else { document.write("bots completed"); } } transaction.oncomplete = function(){ db.close; } } </script> </body> </html>
输出
database opened successfully 1 {id: 1, name: 'jason', branch: 'IT'} 2 {id: 2, name: 'praneeth', branch: 'CSE'} 3 {id: 3, name: 'palli', branch: 'EEE'} 4 {id: 4, name: 'deevana', branch: 'CSE'} bots completed
IndexedDB - Promise 包装器
Promise(承诺)就像回调函数一样,是一种在异步操作完成时告诉你的代码要执行什么操作的技术,而不会停止 JavaScript 运行时的线程。
可以使用 Promise 来代替向异步函数提供回调函数,以便在异步函数完成后运行。
Promise 库由 Jake Archibald 创建,它使用 Promise 而不是事件。
它比传统的 IndexedDB 更易于使用。它简化了 API,同时仍然保持其结构。
这里我们只展示了增强功能,至于为什么我们可以使用 Promise 库,您可以访问以下网站了解更多信息:
它有一些增强功能:
- IDBDatabase
- IDBTransaction
- IDBCursor
IDBDatabase
从对象存储中获取或设置的快捷方式
const value = await db.get(storeName, key); await db.put(storeName, value, key);
从索引中获取的快捷方式
const value = await db.getFromIndex(storeName, indexName, key);
IDBTransaction
tx.store
如果事务只有一个存储区,则 store 属性引用该存储区;否则为 undefined,这时我们使用
const tx = db.transaction('any transaction'); const store = tx.store; tx.objectStore(storeName);
tx.done
当事务成功完成时,.done Promise 解析;否则,它会拒绝并返回事务错误。
const tx = db.transaction(storeName, 'readwrite'); await Promise.all([ tx.store.add('one', 'two'), tx.store.put('three', 'four'), tx.done, ]);
IDBCursor
游标前进方法有:
- Advance
- Continue
- ContinuePrimaryKey
它们返回一个指向游标的 Promise,否则返回 null。
let cursor = await db.transaction(storeName).store.openCursor(); while (cursor) { document.write(cursor.key, cursor.value); cursor = await cursor.continue(); }
IndexedDB - ECMAScript 绑定
首先,什么是 ECMAScript?
ECMAScript(欧洲计算机制造商协会脚本)是一种基于 JavaScript 的脚本语言。
JavaScript ES6 添加了新的语法和功能,使代码更易于阅读,并且我们可以为相同的功能编写更少的代码。ES6 具有许多新特性,例如箭头函数、模板字符串、类解构等。
绑定 - 将对象绑定到函数并使用“this”关键字引用它。
ECMAScript 处理键、值和键路径。
它定义了本规范中定义的键值如何转换为和从 ECMAScript 值转换。
从值中提取键
要使用具有值、键路径和可选多条目标志的键路径从值中提取键,我们需要遵循以下步骤。结果可能是键、无效、失败,甚至是异常。
其中 r 是使用值和键路径对值评估键路径的结果。重新抛出任何异常。如果 r 是失败,则返回失败。
如果多条目标志为假,则 key 为使用 r 将值转换为键的结果;否则,key 为使用 r 将值转换为多条目键的结果。重新抛出任何异常。
如果键无效,则返回无效。
返回键。