18_HTML5 Web IndexedDB 数据库 --[HTML5 API 学习之旅]

HTML5 Web IndexedDB API 是一种在用户浏览器中存储大量结构化数据的机制,它允许存储和检索键值对,其中键可以是任何有效的JavaScript对象。IndexedDB 主要用于需要复杂查询的数据密集型Web应用。

IndexedDB 的特点:

HTML5 Web IndexedDB API 是一种强大的客户端存储解决方案,它允许Web应用程序在用户的浏览器中存储大量的结构化数据。IndexedDB 的特点如下:

  1. 异步操作

    • 所有的数据库操作都是异步的,这意味着它们不会阻塞用户界面或其他脚本执行。这有助于保持网页的响应性。
  2. 键值对存储

    • 数据以对象的形式存储,每个对象与一个主键相关联。主键可以是任何有效的JavaScript对象(如字符串、数字等),也可以是由开发者定义的自动生成的ID。
  3. 事务支持

    • IndexedDB 使用事务来保证数据的一致性和完整性。事务提供了读取、写入和只读三种模式,并且确保了所有操作要么全部成功要么全部失败。
  4. 索引能力

    • 除了主键外,还可以为对象存储创建多个索引,以加速基于非主键字段的数据检索。这些索引使得复杂查询成为可能,比如查找特定范围内的记录或者按照某个属性排序。
  5. 版本控制系统

    • 每个数据库都有一个版本号,当需要修改数据库结构时(例如添加新的对象存储或索引),可以通过升级数据库版本来实现。upgradeneeded 事件会在首次打开数据库或请求更高版本时触发,以便进行必要的更改。
  6. 丰富的API

    • 提供了一系列的方法用于管理数据库、对象存储、索引以及执行CRUD(创建、读取、更新、删除)操作。API设计直观,易于使用。
  7. 大容量存储

    • IndexedDB 支持比本地存储(LocalStorage)更大的数据量,具体大小取决于用户设置和浏览器实现。理论上它可以存储数GB的数据。
  8. 持久化存储

    • 存储在 IndexedDB 中的数据是持久性的,除非被明确地删除或用户清空浏览器缓存,否则数据会一直保存。
  9. 跨域限制

    • IndexedDB 遵循同源策略(Same-origin policy),意味着只有来自相同源(协议、域名、端口)的页面才能访问同一个 IndexedDB 数据库。
  10. 事件驱动架构

    • IndexedDB 使用事件模型来进行错误处理和完成通知。例如,在尝试打开数据库或执行事务时发生的事件可以用来控制流程和响应结果。

通过这些特性,IndexedDB 成为了构建离线Web应用、增强用户体验和性能的一个重要工具。然而,由于其复杂性相对较高,对于简单的数据存储需求,可能会选择更简单的方案如 LocalStorage 或 SessionStorage。

基本使用步骤:

使用 HTML5 Web IndexedDB API 进行基本操作的步骤可以分为以下几个关键阶段:

1. 打开数据库

首先,你需要尝试打开一个已有的数据库或者创建一个新的数据库。这通过 indexedDB.open() 方法完成,该方法接受两个参数:数据库名称和版本号。

var request = indexedDB.open("MyDatabase", 1);

2. 处理升级需求(如果需要)

当首次创建数据库或数据库版本增加时,会触发 upgradeneeded 事件。在这个事件处理函数中,你可以定义数据库结构,包括创建对象存储空间和索引。

request.onupgradeneeded = function(event) {var db = event.target.result;// 创建一个名为 "contacts" 的对象存储空间,设置 "id" 作为主键var objectStore = db.createObjectStore("contacts", { keyPath: "id", autoIncrement: true });// 可选地,在对象存储上创建索引objectStore.createIndex("nameIndex", "name", { unique: false });
};

3. 监听成功和错误事件

为了知道何时数据库已经成功打开以及是否有任何错误发生,你应该添加 onsuccessonerror 事件监听器。

request.onsuccess = function(event) {console.log("数据库打开成功");db = event.target.result; // 保存对数据库的引用
};request.onerror = function(event) {console.error("数据库打开失败");
};

4. 开始事务

在进行任何数据操作之前,你必须开始一个事务。事务指定了要访问的对象存储空间列表,并声明了事务类型(只读 "readonly" 或读写 "readwrite")。

var transaction = db.transaction(["contacts"], "readwrite");

5. 获取对象存储

从事务中获取你要操作的对象存储空间。

var objectStore = transaction.objectStore("contacts");

6. 操作数据

根据你的需求,使用适当的方法来添加、获取、更新或删除数据。

  • 添加/更新:使用 add()put() 方法。
  • 获取:使用 get() 方法。
  • 删除:使用 delete() 方法。
  • 遍历:使用游标(cursor)遍历对象存储中的记录。
// 添加一条新记录到对象存储中
var addRequest = objectStore.add({ name: "张三", email: "zhangsan@example.com" });addRequest.onsuccess = function(event) {console.log("记录添加成功,ID:", event.target.result);
};// 获取指定 ID 的记录
var getRequest = objectStore.get(1);getRequest.onsuccess = function(event) {if (event.target.result) {console.log("找到记录:", event.target.result);} else {console.log("未找到记录");}
};

7. 监听事务完成

监听事务的 complete 事件以确认所有操作都已完成。

transaction.oncomplete = function() {console.log("事务已完成");
};

8. 关闭数据库连接

当你不再需要与数据库交互时,应该关闭数据库连接以释放资源。

db.close();

以上是使用 IndexedDB 的基本流程。根据实际应用的需求,可能还需要更复杂的逻辑和错误处理。记住,IndexedDB 是异步工作的,所以通常你会用回调函数、Promise 或者 async/await 来管理这些异步操作。

示例代码

以下是六个使用 HTML5 Web IndexedDB 的示例,每个示例都展示了不同的功能和用法:

示例 1: 创建数据库和对象存储

// 尝试打开名为 "MyDatabase" 的数据库,如果不存在则创建之,版本号为 1。
var request = indexedDB.open("MyDatabase", 1);// 当需要升级数据库时触发此事件(首次创建或版本号增加)。
request.onupgradeneeded = function(event) {// 获取数据库实例var db = event.target.result;// 创建一个名为 "books" 的对象存储空间,并指定 "isbn" 作为主键。// 每个存储在 "books" 中的对象都必须有一个名为 "isbn" 的属性作为其唯一标识符。var objectStore = db.createObjectStore("books", { keyPath: "isbn" });// 可选地,在这里可以为 "books" 对象存储创建索引,以加速特定字段的查询。// 例如:objectStore.createIndex("titleIndex", "title", { unique: false });
};// 数据库成功打开时触发此事件。
request.onsuccess = function(event) {// 保存对数据库连接的引用(在这个简单的例子中未使用)var db = event.target.result;// 输出确认信息到控制台,表示数据库已经成功打开。console.log("数据库已成功打开");// 注意:在此之后,你通常会开始进行事务操作(如添加、读取、更新或删除数据)。
};// 如果打开数据库过程中出现错误,则触发此事件。
request.onerror = function(event) {// 打印错误信息到控制台,帮助调试问题。console.error("数据库打开失败");
};

在这里插入图片描述

示例 2: 向对象存储中添加记录

function addBook(db, book) {// 开始一个新事务,指定要访问的对象存储空间("books"),并设置为读写模式 ("readwrite")。var transaction = db.transaction(["books"], "readwrite");// 从当前事务中获取名为 "books" 的对象存储空间实例。var objectStore = transaction.objectStore("books");// 向对象存储空间中添加一个新的书本记录。如果主键(这里是指定的 "isbn" 字段)已经存在,则会抛出错误。var addRequest = objectStore.add(book);// 当添加操作成功完成时触发此事件处理程序。addRequest.onsuccess = function(event) {// 输出确认信息到控制台,表示书本已成功添加。console.log("书本添加成功");};// 当整个事务完成时触发此事件处理程序,无论是否有任何操作失败。transaction.oncomplete = function() {// 输出信息到控制台,表示所有事务内的操作已完成。console.log("事务完成");};// 如果事务中的任何一个操作发生错误,则触发此事件处理程序。transaction.onerror = function(event) {// 输出错误信息到控制台,帮助调试问题。console.error("添加失败");};
}// 使用方法:尝试向数据库中添加一本书。
// 注意:这里的 "db" 参数应该是由 indexedDB.open 成功返回的数据库连接对象,而不是字符串 "MyDatabase"。
// 正确的做法是先打开数据库,然后使用返回的数据库连接对象调用 addBook 函数。
var request = indexedDB.open("MyDatabase", 1);request.onsuccess = function(event) {// 获取数据库连接var db = event.target.result;// 现在可以安全地调用 addBook 函数,并传递实际的数据库连接对象。addBook(db, { isbn: '123456789', title: 'HTML5入门' });// addBook(db, { isbn: '12345', title: 'go入门' });// 关闭数据库连接(通常在所有操作完成后进行)// db.close();
};request.onerror = function(event) {console.error("数据库打开失败");
};

在这里插入图片描述

示例 3: 查询特定记录

function getBook(db, isbn) {// 开始一个新事务,指定要访问的对象存储空间("books"),并设置为只读模式 ("readonly")。// 由于我们只是查询数据而不会修改它,所以使用 "readonly" 是合适的。var transaction = db.transaction(["books"], "readonly");// 从当前事务中获取名为 "books" 的对象存储空间实例。var objectStore = transaction.objectStore("books");// 尝试根据提供的 ISBN 获取书本记录。var getRequest = objectStore.get(isbn);// 当获取操作成功完成时触发此事件处理程序。getRequest.onsuccess = function(event) {// 检查是否找到了匹配的书本记录。if (event.target.result) {// 如果找到,输出书本信息到控制台。console.log("找到的书本:", event.target.result);} else {// 如果没有找到对应的 ISBN,输出未找到的信息。console.log("未找到该ISBN的书本");}};// 注意:对于只读事务,通常不需要监听 oncomplete 或 onerror 事件,// 因为这些事件主要用于确保所有写入操作都已成功完成或用于错误处理。
}// 使用方法:尝试从数据库中获取一本书。
// 注意:这里的 "db" 参数应该是由 indexedDB.open 成功返回的数据库连接对象,而不是字符串 "MyDatabase"。
// 正确的做法是先打开数据库,然后使用返回的数据库连接对象调用 getBook 函数。
var request = indexedDB.open("MyDatabase", 1);request.onsuccess = function(event) {// 获取数据库连接var db = event.target.result;// 现在可以安全地调用 getBook 函数,并传递实际的数据库连接对象。getBook(db, '123456789');// 关闭数据库连接(通常在所有操作完成后进行)// db.close();
};request.onerror = function(event) {console.error("数据库打开失败");
};

在这里插入图片描述

示例 4: 更新现有记录

function updateBook(db, updatedBook) {// 开始一个新事务,指定要访问的对象存储空间("books"),并设置为读写模式 ("readwrite")。// 由于我们打算修改数据,因此需要使用 "readwrite" 模式以允许对数据库进行更改。var transaction = db.transaction(["books"], "readwrite");// 从当前事务中获取名为 "books" 的对象存储空间实例。var objectStore = transaction.objectStore("books");// 使用 put() 方法更新或插入书本记录。// 如果对象存储中已存在具有相同主键(这里是指定的 "isbn" 字段)的记录,则该记录会被更新;// 如果不存在这样的记录,则会创建一条新的记录。var putRequest = objectStore.put(updatedBook);// 当 put() 操作成功完成时触发此事件处理程序。putRequest.onsuccess = function(event) {// 输出确认信息到控制台,表示书本已成功更新。console.log("书本更新成功");};// 当整个事务完成时触发此事件处理程序,无论是否有任何操作失败。transaction.oncomplete = function() {// 输出信息到控制台,表示所有事务内的操作已完成。console.log("事务完成");};// 如果事务中的任何一个操作发生错误,则触发此事件处理程序。transaction.onerror = function(event) {// 输出错误信息到控制台,帮助调试问题。console.error("更新失败");};
}// 使用方法:尝试更新数据库中的一本书。
// 注意:这里的 "db" 参数应该是由 indexedDB.open 成功返回的数据库连接对象,而不是字符串 "MyDatabase"。
// 正确的做法是先打开数据库,然后使用返回的数据库连接对象调用 updateBook 函数。
var request = indexedDB.open("MyDatabase", 1);request.onsuccess = function(event) {// 获取数据库连接var db = event.target.result;// 现在可以安全地调用 updateBook 函数,并传递实际的数据库连接对象。updateBook(db, { isbn: '123456789', title: 'HTML5进阶' });// 关闭数据库连接(通常在所有操作完成后进行)// db.close();
};request.onerror = function(event) {console.error("数据库打开失败");
};

在这里插入图片描述

示例 5: 删除记录

function deleteBook(db, isbn) {// 开始一个新事务,指定要访问的对象存储空间("books"),并设置为读写模式 ("readwrite")。// 由于我们打算删除数据,因此需要使用 "readwrite" 模式以允许对数据库进行更改。var transaction = db.transaction(["books"], "readwrite");// 从当前事务中获取名为 "books" 的对象存储空间实例。var objectStore = transaction.objectStore("books");// 使用 delete() 方法尝试根据提供的 ISBN 删除书本记录。// 如果对象存储中存在具有相同主键(这里是指定的 "isbn" 字段)的记录,则该记录会被删除;// 如果不存在这样的记录,则不会有任何操作执行,但也不会抛出错误。var deleteRequest = objectStore.delete(isbn);// 当 delete() 操作成功完成时触发此事件处理程序。// 注意:即使没有找到对应的记录,onsuccess 也会被触发,因为 delete() 成功意味着请求本身已成功执行。deleteRequest.onsuccess = function(event) {// 输出确认信息到控制台,表示书本已成功删除。console.log("书本删除成功");};// 当整个事务完成时触发此事件处理程序,无论是否有任何操作失败。// 这是确保所有操作都已完成的最后一个检查点。transaction.oncomplete = function() {// 输出信息到控制台,表示所有事务内的操作已完成。console.log("事务完成");};// 如果事务中的任何一个操作发生错误,则触发此事件处理程序。// 错误可能由多种原因引起,如违反约束、网络问题等。transaction.onerror = function(event) {// 输出错误信息到控制台,帮助调试问题。console.error("删除失败", event.target.error);};
}// 使用方法:尝试从数据库中删除一本书。
// 注意:这里的 "db" 参数应该是由 indexedDB.open 成功返回的数据库连接对象,而不是字符串 "MyDatabase"。
// 正确的做法是先打开数据库,然后使用返回的数据库连接对象调用 deleteBook 函数。
var request = indexedDB.open("MyDatabase", 1);request.onsuccess = function(event) {// 获取数据库连接var db = event.target.result;// 现在可以安全地调用 deleteBook 函数,并传递实际的数据库连接对象。deleteBook(db, '123456789');// 关闭数据库连接(通常在所有操作完成后进行)// db.close();
};request.onerror = function(event) {// 如果打开数据库过程中出现错误,则输出错误信息。console.error("数据库打开失败", event.target.error);
};

在这里插入图片描述

示例 6: 遍历所有记录

function listAllBooks(db) {// 开始一个新事务,指定要访问的对象存储空间("books"),并设置为只读模式 ("readonly")。// 由于我们只是遍历数据而不会修改它,所以使用 "readonly" 是合适的。var transaction = db.transaction(["books"], "readonly");// 从当前事务中获取名为 "books" 的对象存储空间实例。var objectStore = transaction.objectStore("books");// 使用 openCursor() 方法创建一个游标来遍历对象存储中的所有记录。// 游标允许我们逐条访问对象存储中的记录。objectStore.openCursor().onsuccess = function(event) {// 获取游标对象var cursor = event.target.result;if (cursor) {// 如果存在当前记录,则输出书本信息到控制台。console.log("书名:", cursor.value.title, ", ISBN:", cursor.value.isbn);// 继续移动游标到下一个记录。cursor.continue();} else {// 如果没有更多记录,输出遍历完毕的信息。console.log("遍历完毕");}};
}// 使用方法:尝试列出数据库中的所有书籍。
// 注意:这里的 "db" 参数应该是由 indexedDB.open 成功返回的数据库连接对象,而不是字符串 "MyDatabase"。
// 正确的做法是先打开数据库,然后使用返回的数据库连接对象调用 listAllBooks 函数。
var request = indexedDB.open("MyDatabase", 1);request.onsuccess = function(event) {// 获取数据库连接var db = event.target.result;// 现在可以安全地调用 listAllBooks 函数,并传递实际的数据库连接对象。listAllBooks(db);// 关闭数据库连接(通常在所有操作完成后进行)// db.close();
};request.onerror = function(event) {// 如果打开数据库过程中出现错误,则输出错误信息。console.error("数据库打开失败", event.target.error);
};

在这里插入图片描述

这些示例涵盖了创建数据库、插入数据、查询、更新、删除以及遍历所有记录的基本操作。你可以根据自己的需要调整这些代码片段,以适应更复杂的应用场景。请注意,为了使上述代码正常工作,你需要在适当的位置保存 db 变量(即从 indexedDB.open()onsuccess 回调函数中获取到的数据库连接)。

测试代码下载

html5_api代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/497103.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

e3 1220lv3 cpu-z分数

e3 1220lv3 双核四线程,1.1G频率,最低可在800MHZ运行,TDP 13W。 使用PE启动后测试cpu-z分数。 现在e3 1220lv3的价格落到69元。

【ETCD】【实操篇(十五)】etcd集群成员管理:如何高效地添加、删除与更新节点

etcd 是一个高可用的分布式键值存储,广泛应用于存储服务发现、配置管理等场景。为了确保集群的稳定性和可扩展性,管理成员节点的添加、删除和更新变得尤为重要。本文将指导您如何在etcd集群中处理成员管理,帮助您高效地维护集群节点。 目录 …

【机器学习篇】从新手探寻到算法初窥:数据智慧的开启之门

文章目录 【机器学习篇】从新手探寻到算法初窥:数据智慧的开启之门前言一、什么是机器学习?二、机器学习的基本类型1. 监督学习(Supervised Learning)2. 无监督学习(Unsupervised Learning)3. 半监督学习&a…

Unity游戏环境交互系统

概述交互功能使用同一个按钮或按钮列表,在不同情况下显示不同的内容,按下执行不同的操作。按选项个数分类环境交互系统可分为两种,单选项交互,一般使用射线检测;多选项交互,一般使用范围检测。第一人称游戏单选多选都可以用,因为第一人称人物背对一个可交互对象时显示交…

虚幻引擎结构之UWorld

Uworld -> Ulevel ->Actors -> AActor 在虚幻引擎中,UWorld 类扮演着至关重要的角色,它就像是游戏世界的总指挥。作为游戏世界的核心容器,UWorld 包含了构成游戏体验的众多元素,从游戏实体到关卡设计,再到物…

【Java】面试题 并发安全 (2)

文章目录 可重入锁(ReentrantLock)知识总结1. 可重入锁概念与特点2. 基本语法与使用注意事项3. 底层实现原理4. 面试回答要点 synchronized与lock的区别死锁相关面试题讲解死锁产生的四个条件ConcurrentHashMap2. JDK1.7的ConcurrentHashMap结构添加数据…

yolov3算法及其改进

yolov3算法及其改进 1、yolov3简介2、yolov3的改进2.1、backbone的改进2.1.1、darknet19相对于vgg16有更少的参数,同时具有更快的速度和更高的精度2.1.2、resnet101和darknet53,同样具有残差结构,精度也类似,但是darknet具有更高的…

python报错ModuleNotFoundError: No module named ‘visdom‘

在用虚拟环境跑深度学习代码时,新建的环境一般会缺少一些库,而一般解决的方法就是直接conda install,但是我在conda install visdom之后,安装是没有任何报错的,conda list里面也有visdom的信息,但是再运行代…

Jenkins 构建流水线

在 Linux 系统上安装 Jenkins 服务,以及配置自动化构建项目 前置准备环境:docker、docker-compose、jdk、maven 一、环境搭建 1. Jenkins 安装 (1)拉取镜像 # 安装镜像包,默认安装最新版本 docker pull jenkins/jen…

大数据技术-Hadoop(二)HDFS的介绍与使用

目录 1、HDFS简介 1.1 什么是HDFS 1.2 HDFS的优点 1.3、HDFS的架构 1.3.1、 NameNode 1.3.2、 NameNode的职责 1.3.3、DataNode 1.3.4、 DataNode的职责 1.3.5、Secondary NameNode 1.3.6、Secondary NameNode的职责 2、HDFS的工作原理 2.1、文件存储 2.2 、数据写…

vue3使用element-plus,解决 el-table 多选框,选中后翻页再回来选中失效问题

问题&#xff1a;勾选的数据分页再回来回消失 1.在el-table中加 :row-key"getRowKey" const getRowKey (row) > { return row.id; // id必须是唯一的 }; 2.给type为selection的el-table-column添加上reserve-selection属性 <el-tableref"multipleTab…

go语言的成神之路-筑基篇-gin常用功能

第一节-gin参数绑定 目录 第一节-?gin参数绑定 ShouldBind简要概述 功能&#xff1a; 使用场景&#xff1a; 可能的错误&#xff1a; 实例代码 效果展示 第二节-gin文件上传 选择要上传的文件 选择要上传的文件。 效果展示? 代码部分 第三节-gin请求重定向 第…

五模型对比!Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 光伏功率预测&#xff01;五模型对比&#xff01;Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测(Matlab2023b 多输入单输出) 1.程序已经调试好&#xff0c;替换数据集后&#xff0c;仅运…

12.27【net】【review】【day3】

第三章 l CSMA/CD ( Carrier Sense Multiple Access with Collision Detection) &#xff1a; 载波监听多点接入 / 碰撞 检测。 l 多点接入 &#xff1a; 说明这是总线型 网络。许多 计算机以多点接入的方式连接在一根总线上。 l 载波监听&#xff1a; 即“ 边发送边监听”。…

Python学生管理系统(MySQL)

上篇文章介绍的Python学生管理系统GUI有不少同学觉得不错来找博主要源码&#xff0c;也有同学提到老师要增加数据库管理数据的功能&#xff0c;本篇文章就来介绍下python操作数据库&#xff0c;同时也对上次分享的学生管理系统进行了改进了&#xff0c;增加了数据库&#xff0c…

实现类似gpt 打字效果

1. css的动画&#xff08;animation) css中实现动画有两种方式&#xff1a;transition过渡动画、 animation自定义动画。 具体的可以看MDN链接&#xff1a;https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation 使用keyframes自定义关键帧动画并未其命名使用自定义动…

OpenHarmony-5.PM 子系统(2)

电池服务组件OpenHarmony-4.1-Release 1.电池服务组件 Battery Manager 提供了电池信息查询的接口&#xff0c;同时开发者也可以通过公共事件监听电池状态和充放电状态的变化。电池服务组件提供如下功能&#xff1a; 电池信息查询。充放电状态查询。关机充电。 电池服务组件架…

软考:系统架构设计师教材笔记(持续更新中)

教材中的知识点都会在。其实就是将教材中的废话删除&#xff0c;语言精练一下&#xff0c;内容比较多&#xff0c;没有标注重点 系统架构概述 定义 系统是指完成某一特定功能或一组功能所需要的组件集&#xff0c;而系统架构则是对所有组件的高层次结构表示&#xff0c;包括各…

反应力场的生成物、反应路径分析方法

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

HarmonyOS NEXT 实战之元服务:静态案例效果---妙语集语

背景&#xff1a; 前几篇学习了元服务&#xff0c;后面几期就让我们开发简单的元服务吧&#xff0c;里面丰富的内容大家自己加&#xff0c;本期案例 仅供参考 先上本期效果图 &#xff0c;里面图片自行替换 效果图1完整代码案例如下&#xff1a; import { authentication } …