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、onerroraddEventListener()、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,则此程序将成功执行,并且将创建一个数据库。

Mydatabase

IndexedDB - 安装

Visual Studio Code 是一个重新定义和优化用于构建和调试现代 Web 和云应用程序的代码编辑器。

  • 您可以从其官方网站下载 Visual Studio Code - https://vscode.js.cn

  • 根据您的 PC 配置和操作系统选择您想要的版本。

  • 下载完成后,您可以直接将其安装到您的计算机上。

在 Windows 上安装 Visual Studio Code 安装程序

首先,如上所述下载适用于 Windows 的 Visual Studio Code 安装程序:

  • 下载完成后,运行安装程序。
Visual
  • 然后,接受协议并单击下一步。
Agreement
  • 现在,单击“创建桌面图标”,以便可以从桌面上访问它,然后单击下一步。
Setup
  • 然后,单击安装按钮。
Install
  • 最后,安装完成后,单击完成按钮,Visual Studio Code 将打开。

Code Setup
  • 现在 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 已打开。您会看到此窗口弹出,单击下一步。

Nodejs

步骤 2 - 您将被重定向到“最终用户许可协议”窗口。接受协议并单击下一步

Nodejs Setup

步骤 3 - 在下一个窗口中,您需要选择“目标文件夹”。更改现有文件夹,或使用提到的默认文件夹,然后单击下一步

Destination

步骤 4 - 在“自定义安装”和“原生模块工具”窗口中单击下一步

步骤 5 - 现在,设置已准备好,单击安装以安装所选模块。

Ready Nodejs

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 数据库,您可以看到如下所示的已创建数据库文件:

Indexeddb Files

生成处理程序

事件是在 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;
};

示例

以下示例显示消息“数据库创建成功”。如果数据库创建成功。在这里,我们使用onsuccessonerror 处理程序来显示这些消息。

<!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 数据库。

在右上角,将有一个自定义和控制按钮,单击它。

在列表中选择更多工具选项,然后选择开发者工具

More Tools

在下一页中选择应用程序选项卡,您可以在其中看到 IndexedDB 数据库。

Opening Database

删除数据库

如果存在任何不需要的数据库或其不必要地占用空间,我们可以将其删除。要删除数据库,可以使用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存储,您可以看到如下所示创建的数据库列表。

Test

步骤3 - 点击要删除的数据库。在右侧,您将找到删除数据库按钮。如果单击它,则将删除此数据库。

Delete Database

关闭数据库

要关闭数据库,我们需要使用函数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”,您可以看到新创建的对象存储。

Customers File

定义主键

类似于 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”创建了键路径。

Key Path

创建新的对象存储时,它们会像上面一样在 IndexedDB 文件夹中提到。

您可以同时使用键路径和键生成器。如果数据始终唯一,我们可以使用键路径;如果值发生更改,可以使用键生成器;如果要为每个值更改值,但要提供唯一表示存储的值,则可以使用两者。

定义索引

索引是一种对象存储。它们用于从由指定属性存储的引用对象检索数据。索引使用指定的属性作为其键路径,而不是引用存储的主键。

要创建索引,需要在对象存储实例上调用createIndex()方法。

语法

以下是createIndex()方法的语法:

var myIDBIndex = objectStore.createIndex(indexName, keyPath);
var myIDBIndex = objectStore.createIndex(indexName, keyPath, Parameters);

其中,

  • indexName是创建的索引的名称。

  • Keypath是在创建对象存储时的主键定义

  • 最后一个参数的值可以是uniquemulti-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的内容并展开它,您可以看到创建的表如下:

Key Values

如果您单击名称和学生值,您可以看到索引值如下:

名称索引

# 键(键路径:“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 库,您可以访问以下网站了解更多信息:

https://developers.google.com

它有一些增强功能:

  • 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 将值转换为多条目键的结果。重新抛出任何异常。

  • 如果键无效,则返回无效。

  • 返回键。

广告