首页 > 其他分享 >关于indexedDB的使用

关于indexedDB的使用

时间:2024-11-07 17:32:26浏览次数:5  
标签:indexedDB console log 数据库 request 关于 key 使用 event

一. indexedDB是什么

1.概念

IndexedDB 是一种在浏览器中用于存储大量结构化数据的 NoSQL 数据库

2.特点

存储量大
支持复杂数据结构,能够存储对象和二进制数据,并且可以使用索引来快速检索数据
异步操作
持久性存储

3. 使用场景

离线应用: 可以存储应用所需的数据,以便在离线状态下使用。例如,离线邮件客户端可以将邮件存储在 IndexedDB 中,以便用户在没有网络连接时也能查看邮件。

缓存数据:可以缓存服务器端的数据,以减少网络请求和提高应用的性能。例如,新闻应用可以将最近的新闻文章存储在 IndexedDB 中,以便用户在下次访问时能够更快地加载。

二. 一些概念

1. 基本的操作

IndexedDB 鼓励使用的基本模式如下所示:

打开数据库。
在数据库中创建一个对象存储(object store)。
启动事务,并发送一个请求来执行一些数据库操作,如添加或获取数据等。
通过监听正确类型的 DOM 事件以等待操作完成。
对结果进行一些操作(可以在 request 对象中找到)

2. 概念

(1)数据库 (database):IndexedDB 的数据库是相关数据的容器,每个域名可以创建多个数据库。数据库有版本控制,结构修改(如新增或删除表、索引)只能通过升级版本完成。
(2)对象存储 (object store):IndexedDB 使用对象存储而不是表,并且一个数据库可以包含任意数量的对象存储
(3)事务 (transaction):你需要开启一个事务才能对你创建的数据库进行操作。事务来自于数据库对象,而且你必须指定你想让这个事务跨越哪些对象存储。一旦你处于一个事务中,你就可以访问用于保存数据的对象存储
所有数据操作都在事务中进行,以确保数据的一致性和完整性。事务对象提供了error,abort,complete三个回调方法,监听操作结果。
事务提供了三种模式:readonly、readwrite 和 versionchange。
使用 readonly 或 readwrite 模式都可以从已存在的对象存储里读取记录。但只有在 readwrite 事务中才能修改对象存储。
必须在 versionchange 事务中才能修改数据库的“模式”或结构(包括新建或删除对象存储、索引)(此功能在web workers中可用)。
(4)索引(index):索引用于加速数据检索。每个对象存储可以为不同属性建立索引。
(5)游标(cursor):IDBCursor 对象, 游标用于遍历对象存储中的记录,支持从指定位置开始读取数据,并进行数据的批量操作。

总结: 一个indexedDB 可以有多个数据库,一个数据库有多个对象存储.
数据库开启的操作事务需要指定对象存储,然后进行访问。

三. 简单的封装使用

可以先看MDN给的例子,正常跑通基本逻辑,然后再根据自己的需求封装下。下面的indexedDB.js是工具类,vue文件是调用情况
目的:
给一个key和obj,实现数据的新增,能通过这个key查询,删除,修改
方案:
新增的时候,利用key作为对象存储的键路径, { [key]: key, value: obj}
查询的时候利用get()
删除的时候也通过这个key
修改的也是重置这个

// indexedDB.js
class IndexdedDB {
  constructor (name = 'custom', version = 1) {
    this.request = null
    this.db = null
    this.name = name
    this.version = version
  }
  // 因为获取数据库是异步操作,所以用promise封装下

  getDb (key) {
    return new Promise((resolve, reject) => {
      if (this.db) {
        resolve()
        return
      }

      // 打开数据库
      this.request = window.indexedDB.open(this.name, this.version)
      // 打开数据库的时候就应该创建对象存储
      this.request.onsuccess = (event) => { // 貌似用这个不行
        console.log('获取数据库成功')
        this.db = event.target.result
        resolve()
      }
      // 当你创建一个新的数据库或者增加已存在的数据库的版本号
      this.request.onupgradeneeded = (event) => {
        console.log('新建数据库成功')
        this.db = event.target.result
        this.objectStore = this.db.createObjectStore(key, { keyPath: key })
        this.objectStore.transaction.oncomplete = (event) => {
          console.log('对象存储已经存在')
        }
      }
      this.request.onerror = (event) => {
        // 针对此数据库请求的所有错误的通用错误处理器!
        console.error(`数据库错误:${event.target.errorCode}`)
        reject(new Error(`数据库错误:${event.target.errorCode}`))
      }
    })
  }

  // 新增数据, 用Key做为对象存储名字, 和keyPath
  async addData (key, data) {
    try {
      await this.getDb(key)
      const newData = {
        [key]: key,
        value: JSON.stringify(data)
      }
      // 先判断有没有在对象存储中,有的话就更新
      const res = await this.getData(key)
      if (res) {
        this.editData(key, newData)
        return
      }
      // 将数据保存到新创建的对象存储中。
      const customerObjectStore = this.db
        .transaction(key, 'readwrite')
        .objectStore(key)
      console.log('customerObjectStore', customerObjectStore)
      const addRequest = customerObjectStore.add(newData)
      addRequest.onsuccess = function () {
        console.log('Data added successfully:', newData)
      }
      addRequest.onerror = function (event) {
        console.log('Error adding data:', event.target.errorCode)
      }
    } catch (error) {

    }
  }
  // 获取数据

  async getData (key) {
    return new Promise(async (resolve, reject) => {
      await this.getDb()
      const transaction = this.db.transaction([key])
      const objectStore = transaction.objectStore(key)
      // 使用 get() 要求你知道你想要检索哪一个键
      const request = objectStore.get(key)
      request.onerror = (event) => {
        // 错误处理!
        reject(new Error('获取失败'))
      }
      request.onsuccess = (event) => {
        console.log('request.result', request.result)
        // 对 request.result 做些操作!
        request.result ? resolve(JSON.parse(request.result.value)) : resolve(null)
      }
    })
  }

  async editData (key, newData) {
    const objectStore = this.db
      .transaction([key], 'readwrite')
      .objectStore(key)
    const request = objectStore.get(key)
    request.onerror = (event) => {
    // 错误处理!
    }
    request.onsuccess = (event) => {
      console.log('objectStore', objectStore)
      // 把更新过的对象放回数据库。
      const requestUpdate = objectStore.put(newData)
      requestUpdate.onerror = (event) => {
      // 对错误进行处理
      }
      requestUpdate.onsuccess = (event) => {
      // 成功,数据已更新!
        console.log('成功,数据已更新!', event)
      }
    }
  }

  async delData (key) {
    await this.getDb()
    const request =
      this.db.transaction([key], 'readwrite')
        .objectStore(key)
        .delete(key)
    return new Promise((resolve, reject) => {
      request.onsuccess = (event) => {
        // 删除成功!
        console.log('删除成功')
        resolve()
      }
      request.onerror = function (event) {
        console.log('数据删除失败')
        reject(new Error('删除失败'))
      }
    })
  }
}

const indexedDB = new IndexdedDB()
export default indexedDB

<template>
  <div>
    <el-button type="primary" @click="operation.add">新增</el-button>
    <el-button type="primary" @click="operation.view">查看</el-button>
    <el-button type="primary" @click="operation.del">删除</el-button>
    <el-button type="primary" @click="operation.edit">编辑</el-button>
  </div>
</template>

<script>

import indexedDB from '@/utils/indexedDB'
export default {
  data () {
    return {
      operation: {
        add: this.add,
        view: this.view,
        edit: this.edit,
        del: this.del
      }
    }
  },
  methods: {
    add () {
      console.log('add')
      indexedDB.addData('a', {
        a: 'qiang'
      })
    },
    view () {
      console.log('view')
      indexedDB.getData('a').then(res => {
        console.log('res', res)
      })
    },
    edit () {
      console.log('edit')
      indexedDB.addData('a', { b: 'xiang' }).then(res => {
        console.log('res', res)
      })
    },
    del () {
      console.log('del')
      indexedDB.delData('a').then(res => {
        console.log('删除成功')
      })
    }
  }
}
</script>

<style>

</style>


标签:indexedDB,console,log,数据库,request,关于,key,使用,event
From: https://www.cnblogs.com/listenMao/p/18533403

相关文章

  • Xshell 8 Build 0063绿色特别版发布:功能强大且永久免费使用
    软件介绍Xshell是一款功能强大的Linux远程连接工具,被誉为SSH终端管理器和SSH远程连接主机客户端的最佳选择。它不仅支持多选项卡管理多个主机,还提供了对多种远程协议的支持,如Telnet、Rlogin、SSH/SSHPKCS#11、SFTP和Serial等。此外,Xshell还具备Unicode编码支持、动态端口转发、自......
  • 关于SQL_Errno:1677导致主从复制中断的思考和实践【转】
    1、简单介绍该错误发生的背景:1)数据库版本:MySQL5.7.192)对一个大表修改字段类型DDL(将主键idint变为bigint),为了不影响主库业务,先在从库上执行DDL操作,然后通过主从切换完成最终的大表DDL;在从库执行完DDL后,这时发现复制中断了,报错信息:12Last_SQL_Errno:1677Last_SQ......
  • Failed to load local image resource(在小程序中,`src` 属性需要使用双花括号 `{{ }}`
    文章目录修改WXML文件确保图像文件路径正确检查逻辑层代码总结[渲染层网络层错误]Failedtoloadlocalimageresource/components/antiFakeQuery/imageSrctheserverrespondedwithastatusof500(HTTP/1.1500InternalServerError)(env:Windows......
  • GPU释放威力:在Gymnasium环境中使用稳定基线3在AMD GPU上训练强化学习代理
    GPUUnleashed:TrainingReinforcementLearningAgentswithStableBaselines3onanAMDGPUinGymnasiumEnvironment—ROCmBlogs2024年4月11日作者: DouglasJia.本博客将深入探讨深度强化学习的基本原理,通过一个实用的代码示例,指导您如何利用AMDGPU在Gymnasium......
  • 使用AMD GPU进行图像分类的ResNet模型
    ResNetforimageclassificationusingAMDGPUs—ROCmBlogs2024年4月9日,作者:LoganGrado。在这篇博客中,我们演示了如何使用ROCm在AMDGPU上训练一个简单的ResNet模型来进行CIFAR10数据集的图像分类。在AMDGPU上训练ResNet模型非常简单,仅需安装ROCm和适当的PyTorch库,无......
  • 关于把竖向单个布局在鸿蒙等折叠手机屏中显示成双向布局
    简单描述下需求场景:本来开发的页面在大部分手机里,都是竖向下来展开的,但现在市场上折叠手机越来越多,那么当用户翻转折叠手机,宽度变长了,原本我们的开发页面就会被拉大,显得不好看,所以需要前端针对折叠屏进行兼容,在没打开的时候正常显示,翻转打开的时候就把页面上的div结合百分比......
  • 使用chromedriver抓取网页截图
    前提:1、电脑安装了谷歌浏览器2、下载chromedriver-win64,放到C:\ProgramFiles\Google\Chrome\chromedriver-win64  安装路径chromedriver-win64 下载地址:ChromeforTestingavailability3、importorg.apache.commons.io.FileUtils;importorg.openqa.selenium.Outp......
  • 鸿蒙开发进阶(HarmonyOS)使用通话设备切换组件
     鸿蒙NEXT开发实战往期必看文章:一分钟了解”纯血版!鸿蒙HarmonyOSNext应用开发!“非常详细的”鸿蒙HarmonyOSNext应用开发学习路线!(从零基础入门到精通)HarmonyOSNEXT应用开发案例实践总结合(持续更新......)HarmonyOSNEXT应用开发性能优化实践总结(持续更新......)基本概......
  • Windows 下使用 CMake 安装 Acado
    官方安装教程:Windowsinstallation(1)下载CMake,VisualStudio,Gnuplot,Doxygen,Graphviz,Python,安装路径示例如下:D:\Tools\CodeTools\CMakeD:\Tools\CodeTools\VisualStudioD:\Tools\CodeTools\Gnuplot\gnuplotD:\Tools\CodeTools\Doxygen\doxygenD:\Tools\Co......
  • 教你使用win10实现电脑的定时任务执行
    制作定时任务:步骤一、按下win+s输入“任务计划程序”如下图: 提示:最好以管理员身份运行,避免任务无权限失败的情况。 步骤二、进入到任务计划程序界面 可以看到很多以往程序设置的任务计划信息。步骤三、新建一个任务文件夹,用来放入我们的自定义任务信息 这里我们取......