nodejs33: react中的IndexedDB 原有API+操作库idb+数据库事务

Javascript IndexedDB(Dexie.js) React 存储大量(5-50M)的完整示例 将IndexedDB整合到React应用中,可以为你的应用提供高效的客户端存储解决方案,特别适用于需要存储大量结构化数据或离线功能的场景。为了简化IndexedDB的使用,通常推荐使用封装好的库,如Dexie.js或idb。这些库提供了更简洁和友好的API,方便在React中进行集成。 阅读详情
  • 在 React 中使用 IndexedDB 作为本地数据库存储可以有效地管理大量的数据,比如缓存、离线功能或状态持久化。可以通过索引进行快速查询,支持事务处理,并且异步操作。

特点:

  • 存储键值对。

  • 支持事务。

  • 数据可以分层组织为数据库、对象存储(Object Stores)和索引(Indexes)。

  • 原生IndexedDB API更灵活,但代码较为复杂。 如果需要在项目中频繁操作 IndexedDB,idb 是一个轻量但功能强大的选择;如果需要更复杂的查询和事务管理,Dexie(npm install dexie) 会更适合。

原生IndexedDB的upgradeneeded 事件 & blocked事件

  • upgradeneeded 事件的核心作用是帮助你在数据库版本更新时进行结构调整。你可以利用这个事件来:
    • 迁移数据:从旧版本的数据库结构迁移到新结构。
    • 添加新的存储结构或索引:根据应用的需求,添加新的对象存储或索引,以支持新的功能。
    • 清理旧数据:删除过时的对象存储,移除不再需要的数据结构。
  • 如果在升级数据库时,另一个实例(如其他浏览器标签页)仍在使用该数据库并且没有关闭,它会阻止当前数据库的打开,导致 blocked 事件被触发。你可以通过监听这个事件来处理这种情况。

示例代码

  • 以下代码演示了如何在 IndexedDB 中处理数据库的版本升级过程,包括创建对象存储和索引。它还模拟了打开更高版本的数据库时,如何处理请求被阻塞的情况。
// https://developer.mozilla.org/en-US/docs/Web/API/IDBOpenDBRequest/blocked_event
// 打开数据库,指定数据库名称为 "toDoList",版本号为 4
const DBOpenRequest = window.indexedDB.open("toDoList", 4);

// 当数据库版本需要升级时,触发 onupgradeneeded 事件
DBOpenRequest.onupgradeneeded = (event) => {
  const db = event.target.result; // 获取数据库实例

  // 如果在创建数据库时发生错误,处理错误并打印错误信息
  db.onerror = () => {
    console.log("Error creating database");
  };

  // 在数据库中创建一个名为 "toDoList" 的对象存储(Object Store),以 "taskTitle" 作为主键(keyPath)
  const objectStore = db.createObjectStore("toDoList", {
    keyPath: "taskTitle",  // 任务的标题作为每个数据项的唯一标识符
  });

  // 在 "toDoList" 对象存储中创建多个索引,分别用于按不同字段排序
  objectStore.createIndex("hours", "hours", { unique: false }); // 按小时排序
  objectStore.createIndex("minutes", "minutes", { unique: false }); // 按分钟排序
  objectStore.createIndex("day", "day", { unique: false }); // 按天排序
  objectStore.createIndex("month", "month", { unique: false }); // 按月排序
  objectStore.createIndex("year", "year", { unique: false }); // 按年排序
};

// 当数据库打开成功时,触发 onsuccess 事件
DBOpenRequest.onsuccess = (event) => {
  // 尝试打开同名数据库,但版本号设为 5,目的是测试数据库版本升级
  const req2 = indexedDB.open("toDoList", 5);

  // 如果数据库打开请求被阻塞(例如其他窗口正在使用数据库),触发 "blocked" 事件
  req2.addEventListener("blocked", () => {
    console.log("Request was blocked"); // 打印请求被阻塞的提示
  });
};

解释:

  1. indexedDB.open("toDoList", 4):

    • 这是用来打开或创建一个名为 "toDoList" 的 IndexedDB 数据库,版本号为 4。
    • 如果不存在数据库,会进行创建。
    • 如果该数据库版本已经存在且没有更新,它会打开已有的数据库。如果数据库版本号大于当前存在的版本(如从版本 3 升级到版本 4),则会触发 onupgradeneeded 事件(所以版本是个比较重要的参数,测试时要多次修改版本)。
  2. onupgradeneeded:

    • 该事件在数据库的版本升级时被触发。这里我们在数据库中创建了一个对象存储(toDoList),并定义了几个索引(hours、minutes、day、month、year),这些索引将有助于对存储在数据库中的任务进行排序和查询。
  3. createObjectStore("toDoList", { keyPath: "taskTitle" }):

    • 通过 createObjectStore 创建一个对象存储,keyPath: "taskTitle" 表示对象存储的主键(每个任务的唯一标识符)是 taskTitle 字段。
  4. createIndex():

    • 使用 createIndex 方法为对象存储创建索引,使得在后续查询时可以根据不同的字段(如小时、分钟、日期等)进行排序。

使用 idb 库

安装:

npx create-react-app my-app
cd my-app
npm start
npm install idb // 开源地址:https://github.com/jakearchibald/idb

示例代码:

服务组件

import React, { useEffect, useState } from "react";
import { openDB } from "idb";

// 自定义 Hook:用来初始化并返回 IndexedDB 的实例
export const useIndexedDB = () => {
  const [db, setDb] = useState(null);

  useEffect(() => {
    const initDB = async () => {
      try {
        // 打开或创建数据库
        const database = await openDB("MyDatabase", 1, {
          upgrade(db) {
            // 在升级过程中创建对象存储,类似原生IndexedDB的upgradeneeded 事件
            if (!db.objectStoreNames.contains("Users")) {
              db.createObjectStore("Users", { keyPath: "id" }); // 设置主键为 id,如果数据没有 id 字段,那么你将无法将它存储在这个对象存储中
              // db.createObjectStore(province, { keyPath: 'id', autoIncrement: true }); //这个示例中如果存储的对象没有指定 id 字段,IndexedDB 会自动生成一个唯一的 自增id 字段。
            }
          },
        });
        setDb(database); // 将数据库实例存入 state
      } catch (error) {
        console.error("Failed to open IndexedDB:", error);
      }
    };

    initDB(); // 初始化数据库
  }, []); // 只在组件挂载时运行

  return db; // 返回数据库实例供调用方使用
};
  • objectStoreNames 是一个只读属性,返回数据库中所有的对象存储名称,其提供了一个简单的方式来检查数据库中是否已经存在某个对象存储(objectStore).

组件调用

import React, { useEffect } from "react";
import { useIndexedDB } from "./useIndexedDB";

const App = () => {
  const db = useIndexedDB(); // 使用自定义 Hook 获取数据库实例

  useEffect(() => {
    if (!db) return; // 如果数据库尚未初始化完成,直接返回

    const performDBOperations = async () => {
      try {
        // 添加数据到对象存储
        await db.put("Users", { id: 1, name: "Alice", age: 25 });
        await db.put("Users", { id: 2, name: "Bob", age: 30 });

        // 查询数据
        const user = await db.get("Users", 1); // 根据主键 id 查询
        console.log("Retrieved user:", user);

        // 获取所有数据
        const allUsers = await db.getAll("Users");
        console.log("All users:", allUsers);
      } catch (error) {
        console.error("Error performing DB operations:", error);
      }
    };

    performDBOperations();
  }, [db]); // 依赖于 db,当 db 初始化完成后执行操作

  return <div>IndexedDB Example in React</div>;
};

export default App;
  • 结果:
    在这里插入图片描述

事务

  • 事务(transaction)是 IndexedDB 中用于封装一组操作的对象。事务保证了一组数据库操作的原子性——要么全部成功,要么全部失败。每次修改数据库时,都需要通过事务来执行。
  • 示例:
// 存储每个省份的数据
for (const [province, items] of Object.entries(groupedData)) {
  console.log(province,db)
  const tx = db.transaction(province, 'readwrite');
  const store = tx.objectStore(province);
  
  // 清除现有数据
  await store.clear();
  
  // 存储新数据
  for (const item of items) {
    await store.add(item);
  }
  
  await tx.done;
  console.log(`${province}的数据已存储`);
}

创建事务 (db.transaction)

const tx = db.transaction(province, 'readwrite');
  • db.transaction(province, 'readwrite'):此行代码用于创建一个数据库事务。
    • db: 是通过 openDB 方法打开的 IndexedDB 数据库实例。
    • province: 是一个字符串,表示你要操作的对象存储(object store)的名称。在这段代码中,province 应该是某个省份的名称(如 “Beijing”, “Shanghai” 等)。
    • 'readwrite': 这是事务的模式(transaction mode)。'readwrite' 表示该事务将执行读和写操作。如果你只想读取数据,可以使用 'readonly' 模式。

在这里,db.transaction(province, 'readwrite') 创建了一个事务,该事务将针对名为 province 的对象存储执行读写操作。

  • 事务模式:
    • 'readonly':只能进行读取操作(无法写入数据)。
    • 'readwrite':可以进行读取和写入操作(包括修改、添加和删除数据)。

获取对象存储(objectStore)

  • 存储对象类似关系型数据库中的表
const store = tx.objectStore(province);
  • tx.objectStore(province):这是事务对象 tx 的方法,用于获取指定名称的对象存储(objectStore)。
    • province: 是你在事务中指定的对象存储名称。在这里,province 是一个省份名称(如 “Beijing”)。

    • tx.objectStore(province) 返回的是该事务中的一个对象存储。对象存储是 IndexedDB 中的数据容器,它可以被认为是数据库中的一个表。每个对象存储包含若干个记录,通常每个记录都有一个主键(key)和数据值(value)。

存储对象常用方法

示例:

  • 要 Beijing 这个对象存储中添加数据:
const tx = db.transaction('Beijing', 'readwrite');
const store = tx.objectStore('Beijing');
store.add({ id: 1, name: '北京市' });  // 添加一条数据

可以使用以下常用方法来操作数据:

  • store.add(value, key):添加一个新的记录。value 是数据,key 是主键(可选,如果没有提供,IndexedDB 会自动生成一个主键)。
  • store.put(value, key):更新或插入一个记录。如果记录已经存在,会更新;如果不存在,会插入新记录。
  • store.get(key):根据主键获取一个记录。
  • store.delete(key):删除指定主键的记录。
  • store.clear():清除对象存储中的所有记录。

事务的提交和完成

  • tx.done:表示事务是否完成。当事务完成时,tx.done 会变成 resolved 状态。如果事务有任何错误,tx.done 会变成 rejected。

如果正在执行多个操作,可以通过 await tx.done 来等待事务完成:

await tx.done;
console.log('事务已完成');

CG

  • 更多相关库:
    在这里插入图片描述
use-indexeddb:轻量级(1KB压缩)钩子w承诺在React中可以轻松访问IndexedDB 使用索引数据库 带有承诺的轻量级(gzip压缩)钩子,可在React中轻松访问IndexedDB :anchor: :wrench: 安装 npm i use-indexeddb # npm yarn add use-indexeddb # yarn :books: 故事书 :sparkles: 特征 :leaf_fluttering_in_wind: 轻量级(〜1KB压缩)[无依赖项] :brain: 自动模态类型推断,如useIndexedDBStore<YourInterface>() :check_mark: SSR安全(但不要在其中包装整个应用程序) :crossed_fingers: 基于简单的api :package: 例子 完整的例子 import React from "react" ; import IndexedDBProvider , { useIndexedDBStore } from "use-indexeddb" ; // Database Configuration const idbConfig = { dat 立即下载

相关推荐

useDexie:React Hooks轻松使用Dexie.js IndexDB库

React Hooks使用Dexie.js IndexDB库 Dexie.js是一个华丽的库,可通过简单而强大的语法使用IndexDB 。 但是,如果要在React项目中使用Dexie.js,则需要实现一系列允许异步交互的逻辑。 为此,useDexie是一个包含一系列React Hooks的库,使您可以轻松地将IndexDB用作React应用程序的数据源。 在许多情况下, useDexie允许您完全替换状态库(例如Redux),同时确保更高的执行速度(可以预加载数据)和持久性。 use-dexie挂钩已经过优化,以确保: :fire: 实时刷新依赖于数据源的React元素 :recycling_symbol: 将刷新次数降至最低 :high_voltage: 最高速度和最小内存占用 :flashlight: 动态查询组合 Performance性能和统计实时监控 内容索引 查询表示例 带有选择器回调的示例访存表 useDexieGetTable 参量 回叫示例

前端离线存储能力:如何在 React 中巧妙运用IndexedDB

当我们开发复杂的Web应用时,常常需要在客户端存储大量数据。你可能听过 `localStorage`或者 `sessionStorage`,但它们在存储空间和功能上都有限。而今天我们要聊的,是一个功能更强大的技术:**IndexedDB**。IndexedDB是一个运行在浏览器中的非关系型数据库。它让你能够存储大量的数据,并具有高性能的查询能力。不像localStorage只能存储字符串,IndexedDB可以存储各种类型的数据,比如文件、Blob,以及你可以想到的其

乐闻世界 3008

管理单个 indexDB 项目的 React 副作用挂钩。

react-use-idb (useIdb) 管理单个 indexDB 项目的 React 副作用挂钩。 对 useLocalStorage 的直接替换。 为什么 ? LocalStorage 是同步的,因此存在性能问题 LocalStorage 也受到限制,仅存储字符串并且不提供用于序列化/反序列化数据的默认机制。 相反,我们可以依靠 indexDB 进行结构克隆。 用法 import { useIdb } from 'react-use-idb' const Demo = () => { const [value, setValue] = useIdb('my-key', 'foo') return (

React之IndexedDB之Dexie

React之IndexedDB之Dexie 一、概述 IndexedDB 是一个基于 JavaScript 的面向对象数据库,类似于基于 SQL 的 RDBMS,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。 我们这里使用Dexie.js来操作IndexedDB。 二、使用 官方文档:https://dexie.org/docs/Tutorial/React 示例 创建数据库 import Dexie, { Table } from 'dexie'; exp

2ker的博客 1796

AURIX™ TC49x芯片手册中文分享(二)

主要内容为第一章、功能模块的特征

xibaofenqi的博客 1562

【网络原理】HTTP 请求 (Request)详解

【网络原理】HTTP 请求 (Request)详解,认识URLquery string关于 URL encode, GET方法,POST 方法,GET 和 POST 的区别,User-Agent (简称 UA),Referer,Cookie

ZXT的博客 1万+

前端数据缓存技术选型及应用技巧

前端缓存的选型需要贴合业务场景来选择,大家也可以交流分享下自己遇到过的经典场景,看使用哪种方案、如何设计比较好。

Senar的博客 1331

Win11安装Office2021

windows11安装office2021。

1万+

前端本地存储数据库存储之IndexedDB

IndexedDB数据库没有我们想象的那么复杂,了解了它的几个基本概念,上手还是很快的,无非就是增删改查等等,虽然可能开发中用的少,但是了解一下不至于真正用到的时候两眼抓瞎。

nihaio25的博客 2994

「大模型学习」(11)kv cache与vllm详解,一文读懂!

Key(键):表示上下文的特征。Value(值):表示上下文的内容。Query(查询):表示当前 token 的查询向量。AttentionQKVsoftmaxQKTdkVAttentionQKVsoftmaxdk​​QKT​V),每次生成一个新 token(比如下一个词),模型会再次查看之前的所有K和V,以计算当前 token 的注意力。问题:每次都重新计算之前的 K/V 很浪费!项目维度(简化)含义Q当前 token 的查询向量。

qq_43044037的博客 5405

【R】R画图不显示中文问题

系统mac os 11 RstutioVersion1.2.1335 RVersion3.6.2 画图里的中文一直显示成方框。 ggplot()+geom_point(aes(x=ta1$X2011年,y=ta1$X2012))+ xlab("2011年")+ylab("2021年") 解决方案: 使用showtext。 install.packages("showtext", repos = "https://mirrors.ustc.edu.cn/CRAN/") in...

weixin_41772125的博客 1万+

indexDB 前端操作

indexDB 是一种低级api ,用于客户端存储大量结构化数据。该api使用索引来实现对该数据的高性能搜索。 为应用提供离线版本 indexdb 特点 键值存储。 IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,...

齐枫的博客 3142

一张图读懂 SAP S/4HANA Cloud 与 SAP BTP 的扩展版图

本文解析了SAP S/4HANA Cloud的扩展技术谱系,提出扩展应分为on-stack(系统内)和side-by-side(并行)两种路径,并沿着低代码到专业代码的能力梯度进行分层。on-stack扩展包括面向业务人员的Key User Extensibility和面向开发者的Developer Extensibility,强调贴近核心业务对象;side-by-side扩展则依托SAP BTP平台,提供SAP Build低代码工具、CAP开发框架和ABAP云环境三种方案,支持解耦创新。文章通过五个真实案

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 250

使用idb操作IndexedDB

idb是当前最流行的 IndexedDB 包装库,国内对此的介绍极少;本文为一篇翻译过来的教程。

io 4301

UNet改进(19):基于残差注意力模块Residual Attention的高效分割网络设计

本文提出一种结合注意力机制的改进UNet网络,通过引入残差注意力模块(ResidualAttentionBlock)增强医学图像分割性能。该网络在传统UNet的U型结构基础上,创新性地将轻量级注意力机制与残差连接相结合,在编码器-解码器各层级实现特征重标定。改进后的网络具有三方面优势:通过注意力机制自适应聚焦关键特征区域,利用残差连接缓解梯度消失问题,采用模块化设计灵活配置注意力位置。

2501_91516851的博客 780

智能车图像处理2-入门级分析1 ---基础扫线

PS :入门级文章适合新手,如果已经有基础可以去看进阶篇文章。

taiyuezyh的博客 7746

React Indexed DB 开源项目教程

React Indexed DB 开源项目教程 本教程将引导您了解并使用 react-indexed-db 开源项目,通过它您可以轻松地在React应用中集成IndexedDB存储功能。该项目基于GitHub仓库 https://github.com/assuncaocharles/react-indexed-db.git,旨在简化IndexedDB的使用流程。 1. 项目目录结构及介绍 以下是r...

gitblog_00127的博客 473

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

推荐项目:React IndexedDB Hook - 拥抱前端本地存储的高效之道

推荐项目:React IndexedDB Hook - 拥抱前端本地存储的高效之道 在现代Web开发中,提升用户体验已成为核心目标之一。而高效、灵活地管理本地数据,无疑是实现这一目标的关键环节。今天,我们为你介绍一个强大的开源库——React IndexedDB Hook,它为React开发者提供了一个优雅的接口,简化了IndexedDB的使用,让本地数据存储变得更加简单和直观。 项目介绍 Rea...

gitblog_01191的博客 567

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

前端使用indexedDB

新项目中突然要前端存30M的文件作为数据,前端做业务驱动, sessionStorage、localStorage都无法存储这么大的数据,只好转用indexedDB,只记录一下最基础的使用。3、使用场景:初始化请求数据存入indexedDB,后续每次请求覆盖indexedDB中的数据。

qq_16785561的博客 772

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

IndexedDB 数据库的使用

前端的存储方式 前端的存储,可以使得页面交互更加友好,特别是在保存草稿,网络差的情况下对用户来说是很有用的。 前端的存储方式有多种,像 Local storage、Session storage、IndexedDB、Web Sql、Cookies等这几种。 使用场景 我们比较常见的是本地存储,像用户的基本信息,需要在多个页面需要的时候,可以在登入的时候存储在本地,及时下次退出之后,登入信息还可以保存,这样减少了用户的输入量。 但是,它也是有缺点的,它的存储大小只有5M,只能满足相对较小的数据存储,如果是大

qq_40409143的博客 1590

HTML5 本地存储之IndexedDB封装及最详细教程

indexDB 索引数据库,操作简便(目前主流浏览器正努力实现对index DB的支持),最主要的是我们可以很轻松的通过JS极其方便的对其调用; 现今多数业务需要离线访问、或将大量数据储存在客户端,减少从服务器获取数据,直接从本地获取数据。 目前做的业务中需要将图片及其他数据存储在本地、在有网时将其发送给服务器;考虑到手机图片过大、localStorage存储大小限制为5M、所以对indexDB做一封装、以便往后不再需要研究其中api、直接copy文件、调用其中方法;; 本以为会有能说清楚的博客、发现大家都

xuewenjie0217的博客 5244

本地存储之IndexedDB

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34167043的博客 549

IndexedDB教程

介绍了 indexedDB 基础 API,以及相关的增删改查封装

w1405270578的博客 1276

react + express连接mongodb数据库

console.log('数据库已链接');1)创建db/mongoose.js 用于导出mongoose对象。//1.引入mongoose对象。//2.创建____Schema。//3.对应的____Model。4.npm i cors --- 用于异步请求。//4.导出____Model。//1.引入mongoose。//4.导出mongoose。2)创建db/model.js。2.在bin/www中修改端口号为8000。1.express项目名。//写一个简单的接口。3.在app.js配置cors。

LMYDQ的博客 630

利用indexDB带你手把手构建一个前端数据库体系

IndexDB 是一个运行在浏览器上的非关系型数据库。既然是数据库了,那就不是 5M、10M 这样小打小闹级别了。理论上来说,IndexDB 理论上是没有存储上限的一般来说不会小于 250M。它不仅可以存储字符串,还可以存储二进制数据。为了后面能看懂代码,这里对 IndexDB 的 api 做一个简要的介绍。整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。

军火库 2323

IDB 开源项目指南

IDB(由dmayer维护)是一个围绕Electron构建的用于在Node.js环境中执行IndexedDB操作的库。这个项目旨在填补Node.js环境中原生不支持IndexedDB这一空白,使得开发者能够在服务器端或混合应用程序中利用IndexedDB的强大本地存储能力。通过IDB,开发者可以实现离线数据处理、缓存以及数据同步等功能,增强了web应用的可扩展性和脱机工作能力。 ## 项目快速启...

gitblog_00238的博客 631
上一篇: 网页脚本 000:tampermonkey浏览器插件开发基础
下一篇: 【电路笔记 TMS320F28335DSP】闪存空间 CMD 工程配置 + error #10099-D: program will not fit into available memory.
FakeOccupational
博客等级 码龄6年 2万+粉丝 1727原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值