当前位置: 首页 > article >正文

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

文章目录

  • 往期回顾
  • 项目实战
    • 初始化表
    • 获取列表
    • 新增表的数据项
    • 获取详情
      • 根据ID获取详情
      • 根据其他字段获取详情
    • 删除数据
  • 总结

往期回顾

在这里插入图片描述

在之前的文章中,我们介绍了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 声明。

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


http://www.kler.cn/a/460278.html

相关文章:

  • C# 设计模式(结构型模式):组合模式
  • MySQL 03 章——基本的SELECT语句
  • Python判别不同平台操作系统调用相应的动态库读写NFC
  • 活动预告 |【Part2】Microsoft 安全在线技术公开课:安全性、合规性和身份基础知识
  • MySQL面试题(updating)
  • 【QT】实现RestFul接口
  • win10 重装系统中 或 电脑恢复重置中的 优化步骤
  • 寄存器总结
  • 开发小工具:ping地址
  • django StreamingHttpResponse fetchEventSource实现前后端流试返回数据并接收数据的完整详细过程
  • PHP框架+gatewayworker实现在线1对1聊天--mysql数据库(3)
  • Spring boot + Hibernate + MySQL实现用户管理示例
  • logback之自定义过滤器
  • 【AndroidAPP】权限被拒绝:[android.permission.READ_EXTERNAL_STORAGE],USB设备访问权限系统报错
  • C语言一维数组与指针运算
  • 《计算机组成及汇编语言原理》阅读笔记:p133-p159
  • WPF的下拉复选框多选,数据来源数据库的表
  • 【人工智能机器学习基础篇】——深入详解深度学习之神经网络基础:理解前馈神经网络与反向传播算法
  • 医疗数仓配置Flume
  • 使用maven-mvnd替换maven大大提升编译打包速度
  • sublime 文件高亮设置
  • vim编辑器实用设置
  • VirtualBox新版本报错 Invalid installation directory解决方案
  • C#封送类
  • Tesseract-OCR 文字识别
  • 【Spring】Spring DI(依赖注入)详解—自动装配—byType实现原理