首页 > 其他分享 >前端超大缓存IndexDB、入门及实际使用

前端超大缓存IndexDB、入门及实际使用

时间:2025-01-02 17:55:03浏览次数:3  
标签:function 缓存 const 超大 objectStore request event transaction IndexDB

文章目录

往期回顾

在这里插入图片描述

在之前的文章中,我们介绍了IndexDB vs Cookies vs Session这几个的对比,但是没有做实际项目的演示,今天我们用实际项目来演示IndexDB的便捷性。

首先需要明确的是IndexDB的适用场景:

  • 离线应用
  • 大型网页游戏
  • 数据缓存
  • 复杂数据管理和查询

项目实战

我们用纯IndexDB来实现表格的基本增删改查的功能!

这只是一个引子,实际上你可以将本示例的思想用于更大的场景
在这里插入图片描述

初始化表

按如下代码格式初始化IndexDB,如果初始不存在,则创建表CryptSetting(实际名称可自定义)和表的字段名,如下objectStore.createIndex()方法。

创建表是最好声明一个自增的唯一主键id,本例为projectId

let db = null;
// 初始化indexDB数据库
async function initDB() {
  const request = window.indexedDB.open('CryptSetting', 1);

  // success 事件表示成功打开数据库
  request.onsuccess = (event) => {
    db = event.target.result;
    // 打开成功之后需要获取数据库列表
    getList()
  };

  // error 事件表示打开数据库失败
  request.onerror = (event) => {
    console.log('打开 IndexedDB 失败');
  };

  // 如果指定的版本号,大于数据库的实际版本号,就会发生数据库升级事件 upgradeneeded
  request.onupgradeneeded = function (e) {
    db = e.target.result;
    let objectStore;
    if ( !db.objectStoreNames.contains('CryptSetting') ) {
      // 索引名称、索引所在的属性、配置对象(说明该属性是否包含重复的值)
      objectStore = db.createObjectStore('CryptSetting', { keyPath: 'projectId', autoIncrement: true });
      objectStore.createIndex('project_name', 'projectName', { unique: false });
      objectStore.createIndex('key_1', 'key', { unique: false });
      objectStore.createIndex('iv_1', 'iv', { unique: false });
    }
  };
}

初始化之后,会在控制台看到如下:
在这里插入图片描述

获取列表

初始化之后,需要获取数据库列表

请注意以下的写法,列表只能一条条获取,可以先声明一个空数组接收,最后统一赋值
此处用到了continue方法
效率还是很快的,不要以为一条条获取速度就慢!

// 获取配置列表
async function getList() {
  loading.value = true
  const transaction = db.transaction([ 'CryptSetting' ], 'readonly');
  const objectStore = transaction.objectStore('CryptSetting');
  const request = objectStore.openCursor(); // 获取所有配置

  // indexDB是一个个获取数据的,所以用数组接收,最后统一赋值
  const tempArr = []
  request.onsuccess = function (event) {
    const cursor = event.target.result;
    if (cursor) {
      tempArr.push(cursor.value);
      cursor.continue(); // 继续遍历下一条数据
    } else {
      tableData.value = tempArr
      loading.value = false
    }
  };

  request.onerror = function () {
    errorTip('获取列表失败')
    loading.value = false
  };
}

新增表的数据项

表初始化之后,其实还是空的表,所以上面获取值为空,所以此时需要往里面添加数据,按如下格式写即可。

注意:此处不传projectId,因为它是主键ID、会自动生成,按123456,
如果6被删除了,下次自动生成的ID为7

function addSettings() {
  const transaction = db.transaction([ 'CryptSetting' ], 'readwrite');
  const objectStore = transaction.objectStore('CryptSetting');
  const { projectName, key, iv } = formData.value // 此处不传projectId,自动生成
  const request = objectStore.add({
    projectName,
    key,
    iv
  });

  request.onsuccess = function (event) {
    successTip('添加成功')
  };

  request.onerror = function (event) {
    errorTip()
  };
}

新增之后,效果如下:在这里插入图片描述

获取详情

根据ID获取详情

// 获取配置详情
function getSettingsDetail(id) {
  const transaction = db.transaction([ 'CryptSetting' ], 'readonly');
  const objectStore = transaction.objectStore('CryptSetting');
  const request = objectStore.get(id);

  request.onsuccess = function (event) {
    const result = event.target.result;
    if (result) {
      title.value = '编辑项目配置'
      isEdit.value = true
      dialogVisible.value = true
      formData.value = result
    } else {
      errorTip('获取失败')
    }
  };

  request.onerror = function(event) {}
}

根据其他字段获取详情

在 IndexedDB 中,get 方法只能根据主键(keyPath)来查询数据。如果你需要根据其他字段(如 projectName、key、iv 等)来查询数据,可以使用索引(index)。索引允许你根据非主键字段来查询数据。
以下示例为:根据 projectName 查询配置详情

function getSettingsByProjectName(projectName) {
  console.log('projectName', projectName);
  const transaction = db.transaction(['CryptSetting'], 'readonly');
  const objectStore = transaction.objectStore('CryptSetting');
  const index = objectStore.index('project_name');
  const request = index.get(projectName);

  request.onsuccess = function (event) {
    const result = event.target.result;
    if (result) {
      title.value = '编辑项目配置';
      isEdit.value = true;
      dialogVisible.value = true;
      formData.value = result;
    } else {
      errorTip('获取失败');
    }
  };

  request.onerror = function (event) {
    console.error('查询失败', event);
    errorTip('查询失败');
  };
}

删除数据

// 删除配置,传参id
function deleteSettings(id) {
  const transaction = db.transaction([ 'CryptSetting' ], 'readwrite');
  const objectStore = transaction.objectStore('CryptSetting');
  const request = objectStore.delete(id); // 假设我们要删除id的记录

  request.onsuccess = function (event) {
    successTip('删除成功');
  };

  request.onerror = function (event) {
    errorTip('删除失败');
  };
}

总结

IndexDB的许多思想都和mysql有相似之处。
我们发现,基本上增删改查都有相似的代码

  const transaction = db.transaction(['CryptSetting'], 'readwrite');
  const objectStore = transaction.objectStore('CryptSetting');

其实这段代码是不能省略的,因为它:

  • 事务的独立性:
    • 每个事务都是独立的,不能共享。一旦事务完成,就不能再使用它。
    • 如果尝试在多个操作中重用同一个事务,会导致错误。
  • 数据一致性:
    • 每个事务确保数据的一致性。如果多个操作共享同一个事务,一个操作失败会导致整个事务回滚,影响其他操作。
  • 错误隔离:
    • 每个事务有自己的错误处理机制。如果一个事务失败,其他事务不会受到影响。
    • 通过每次操作声明新的事务,可以更好地控制错误处理和回滚。

为了确保数据操作的正确性和一致性,每次进行新增、删除、更新等操作时都需要声明新的 transaction 和 objectStore。这是 IndexedDB 的设计原则,确保每个操作都是独立且可靠的。因此,不能省略每次操作时的 transaction 和 objectStore 声明。

以上仅为简易的入门,及细节讲解,更多细节需要实战中探索,感谢打赏!

标签:function,缓存,const,超大,objectStore,request,event,transaction,IndexDB
From: https://blog.csdn.net/yan1915766026/article/details/144840018

相关文章

  • 缓存雪崩及解决办法
    缓存雪崩是指在缓存系统中,由于大量缓存数据在同一时间失效,导致大量原本可以直接从缓存中获取数据的请求直接转向数据库或后端服务,从而给数据库或后端服务带来巨大的压力,甚至可能导致系统崩溃的一种现象。以下是缓存雪崩的一些特点和影响:一、产生原因过期时间设置不合理:......
  • 为什么需要浏览器缓存?
    浏览器缓存对于前端开发来说非常重要,主要有以下几个原因:提高加载速度:当用户再次访问已经访问过的页面时,如果页面内容没有变化,浏览器可以直接从本地缓存中加载资源,而不需要从服务器重新下载。这大大减少了网络请求的时间和带宽消耗,从而提高了页面的加载速度。减轻服务器压力:......
  • 由 Mybatis 源码畅谈软件设计(七):从根上理解 Mybatis 一级缓存
    作者:京东保险王奕龙本篇我们来讲一级缓存,重点关注它的实现原理:何时生效、生效范围和何时失效,在未来设计缓存使用时,提供一些借鉴和参考。1.准备工作定义实体publicclassDepartment{publicDepartment(Stringid){this.id=id;}privateStri......
  • LVGL-C 实现一个文件持久性缓存,用于存储配置相关数据
    实现功能描述:基于linux嵌入式平台开发App,在未移植数据库的情况下,文件存储是一个不错的持久性数据存储手段。创建代码文件:configcache.hconfigcache.c1.数据结构的结构体封装点击查看代码//配置信息结构typedefstruct{char*key;char*v......
  • mosdns 和 smartdns 都是常用的 DNS 代理工具,主要用于提高 DNS 查询的速度和效率,支持
    mosdns和smartdns都是常用的DNS代理工具,主要用于提高DNS查询的速度和效率,支持智能DNS查询、DNS缓存等功能。下面是这两个DNS工具的对比表格,帮助了解它们的区别和特点:功能/特性mosdnssmartdns主要功能提供快速的DNS查询服务,支持DNS缓存、加速等功能提......
  • nuxt 添加 redis 缓存
    这个文章的主要目的是通过redis缓存nuxt2中服务端渲染的页面。从而优化加载速度以及减轻服务端的压力。Nuxt是什么Nuxt.js是一个基于Vue.js的开源框架,旨在为开发者提供一个简单的方式来构建高性能的Vue应用。它提供了许多功能,使得开发服务器端渲染(SSR)、静态站点生成......
  • 本地更新正常但上传空间后无法更新缓存
    当您在本地环境中能够顺利地更新网站后台并保存更改,但在上传至虚拟主机后却遇到了无法更新缓存的问题时,这通常意味着存在某些配置差异或环境兼容性问题。以下是一些常见的原因及解决方案,帮助您更好地理解和处理这种情况:服务器环境差异:PHP版本不匹配:不同服务器可能运行着不同......
  • [4427] 13 缓存优化:那些基于缓存的优化方案
    上节课的思考题是Webpack4中TreeShaking的触发条件有哪些?我们一起来回忆一下,要让引入的模块支持TreeShaking,一般有4点需要注意:引入的模块需要是ES6类型的,CommonJS类型的则不支持。引入方式不能使用default。引用第三方依赖包的情况下,对应的package.json......
  • 【Spring】三级缓存解决循环依赖问题
    参考地址:Spring循环依赖:https://zhuanlan.zhihu.com/p/700890658Spring三级缓存解决循环依赖的问题:https://blog.csdn.net/Trong_/article/details/134063622  ==================================================================1.什么是循环依赖?1>说白是一个或多个对......
  • 146. LRU 缓存
    题目链接解题思路:用链表+哈希表。链表从头串到尾,淘汰时,从尾部开始淘汰。每次get时,如果找到了,则把这个节点移到头部。每次put,新建一个节点,放在头部,如果容量不够了,则淘汰尾部的数据。哈希表的作用是,能快速通过key找到链表中的节点。代码classLRUCache:classNode:......