indexDB入门到精通

news2025/1/16 1:45:57

前言
由于开发3D可视化项目经常用到模型,而一个模型通常是几m甚至是几十m的大小对于一般的服务器来讲加载速度真的十分的慢,为了解决这个加载速度的问题,我想到了几个本地存储的。

首先是cookie,cookie肯定是不行的,因为最多以只能存4k,

其次localStorage,最多能存5m(不是一个key的大小,是所有key的总大小最多加起来最多5m),相对于cookie已经打了很多了。但是当遇到大模型还是不够,实际开发中大部分模型都是10m-30m的。

经过网上的相关资料的搜索了解到了indexDB,indexD就正好合适了,因为我发现我常用的3d框架three.js他们也是使用indexDB去做存储,而且存储大小是250m以上(受计算机硬件和浏览器厂商的限制)。

一、直接上代码更看结果更直观

懒人直接看入门的全部代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
  <title>Title</title>
  <link href="./favicon.png">
</head>
<body>
</body>
<script>
  let dbName = 'helloIndexDB', version = 1, storeName = 'helloStore'
 
  let indexedDB = window.indexedDB
  let db
  const request = indexedDB.open(dbName, version)
  request.onsuccess = function(event) {
    db = event.target.result // 数据库对象
    console.log('数据库打开成功')
  }
 
  request.onerror = function(event) {
    console.log('数据库打开报错')
  }
 
  request.onupgradeneeded = function(event) {
    // 数据库创建或升级的时候会触发
    console.log('onupgradeneeded')
    db = event.target.result // 数据库对象
    let objectStore
    if (!db.objectStoreNames.contains(storeName)) {
      objectStore = db.createObjectStore(storeName, { keyPath: 'id' }) // 创建表
      // objectStore.createIndex('name', 'name', { unique: true }) // 创建索引 可以让你搜索任意字段
    }
  }
 
 
  // 添加数据
  function addData(db, storeName, data) {
    let request = db.transaction([storeName], 'readwrite') // 事务对象 指定表格名称和操作模式("只读"或"读写")
      .objectStore(storeName) // 仓库对象
      .add(data)
 
    request.onsuccess = function(event) {
      console.log('数据写入成功')
    }
 
    request.onerror = function(event) {
      console.log('数据写入失败')
      throw new Error(event.target.error)
    }
  }
 
  // 根据id获取数据
  function getDataByKey(db, storeName, key) {
      let transaction = db.transaction([storeName]) // 事务
      let objectStore = transaction.objectStore(storeName) // 仓库对象
      let request = objectStore.get(key)
 
      request.onerror = function(event) {
        console.log('事务失败')
      }
 
      request.onsuccess = function(event) {
        console.log('主键查询结果: ', request.result)
      }
  }
 
  // 根据id修改数
  function updateDB(db, storeName, data) {
    let request = db.transaction([storeName], 'readwrite') // 事务对象
      .objectStore(storeName) // 仓库对象
      .put(data)
 
    request.onsuccess = function() {
      console.log('数据更新成功')
    }
 
    request.onerror = function() {
      console.log('数据更新失败')
    }
  }
 
  // 根据id删除数据
  function deleteDB(db, storeName, id) {
    let request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(id)
 
    request.onsuccess = function() {
      console.log('数据删除成功')
    }
 
    request.onerror = function() {
      console.log('数据删除失败')
    }
  }
 
  // 由于打开indexDB是异步的加个定时器避免 db对象还没获取到值导致 报错
  setTimeout(() => {
    addData(db, storeName, {
      id: new Date().getTime(), // 必须且值唯一
      name: '张三',
      age: 18,
      desc: 'helloWord'
    })
 
    getDataByKey(db, storeName, 1638160036008)
 
    updateDB(db, storeName, {id: 1638164880484, desc: '修改的内容'})
 
    deleteDB(db, storeName, 1638164870439)
  }, 1000)
 
</script>
</html>

第一步:准备环境和基本的html页面

 基本的html代码

​<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
  <title>Title</title>
</head>
<body>
</body>
<script>
  
</script>
</html>
 

第二步:打开数据库(如果没有自动创建)

  let dbName = 'helloIndexDB', version = 1, storeName = 'helloStore'
 
  let indexedDB = window.indexedDB
  let db
  const request = indexedDB.open(dbName, version)
  request.onsuccess = function(event) {
    db = event.target.result // 数据库对象
    console.log('数据库打开成功')
  }
 
  request.onerror = function(event) {
    console.log('数据库打开报错')
  }
 
  request.onupgradeneeded = function(event) {
    // 数据库创建或升级的时候会触发
    console.log('onupgradeneeded')
    db = event.target.result // 数据库对象
    let objectStore
    if (!db.objectStoreNames.contains(storeName)) {
      objectStore = db.createObjectStore(storeName, { keyPath: 'id' }) // 创建表
      // objectStore.createIndex('name', 'name', { unique: true }) // 创建索引 可以让你搜索任意字段
    }
  }

运行如上面的代码后打开控制台可以看到如下效果,数据库已经创建完成了,此时什么数据都没有

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5reL6Zuo5LiA55u06LWwfg==,size_19,color_FFFFFF,t_70,g_se,x_16

第三步:存入一个helloWorld 

  // 添加数据
  function addData(db, storeName, data) {
    let request = db.transaction([storeName], 'readwrite') // 事务对象 指定表格名称和操作模式("只读"或"读写")
      .objectStore(storeName) // 仓库对象
      .add(data)
 
    request.onsuccess = function(event) {
      console.log('数据写入成功')
    }
 
    request.onerror = function(event) {
      console.log('数据写入失败')
      throw new Error(event.target.error)
    }
  }
 
  // 由于打开indexDB是异步的加个定时器避免 db对象还没获取到值导致 报错
  setTimeout(() => {
    addData(db, storeName, {
      id: new Date().getTime(), // 必须且值唯一
      name: '张三',
      age: 18,
      desc: 'helloWord'
    })
  }, 1000)

刷新页面后可以看到如下结果,此时我这里已经存进去了,(我刷新了两次所以有两条数据)

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5reL6Zuo5LiA55u06LWwfg==,size_20,color_FFFFFF,t_70,g_se,x_16

 第四步:封装删除,查询,修改方法并分别执行查看结果

 
  // 根据id获取数据
  function getDataByKey(db, storeName, key) {
      let transaction = db.transaction([storeName]) // 事务
      let objectStore = transaction.objectStore(storeName) // 仓库对象
      let request = objectStore.get(key)
 
      request.onerror = function(event) {
        console.log('事务失败')
      }
 
      request.onsuccess = function(event) {
        console.log('主键查询结果: ', request.result)
      }
  }
 
  // 根据id修改数
  function updateDB(db, storeName, data) {
    let request = db.transaction([storeName], 'readwrite') // 事务对象
      .objectStore(storeName) // 仓库对象
      .put(data)
 
    request.onsuccess = function() {
      console.log('数据更新成功')
    }
 
    request.onerror = function() {
      console.log('数据更新失败')
    }
  }
 
  // 根据id删除数据
  function deleteDB(db, storeName, id) {
    let request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(id)
 
    request.onsuccess = function() {
      console.log('数据删除成功')
    }
 
    request.onerror = function() {
      console.log('数据删除失败')
    }
  }
 
 
 
  // 由于打开indexDB是异步的加个定时器避免 db对象还没获取到值导致 报错
  setTimeout(() => {
    // addData(db, storeName, {
    //   id: new Date().getTime(), // 必须且值唯一
    //   name: '张三',
    //   age: 18,
    //   desc: 'helloWord'
    // })
 
    getDataByKey(db, storeName, 1638160036008)
 
    updateDB(db, storeName, {id: 1638164880484, desc: '修改的内容'})
 
    deleteDB(db, storeName, 1638164870439)
  }, 1000)

执行上面的代码后结果后,我这边的结果如下,

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5reL6Zuo5LiA55u06LWwfg==,size_20,color_FFFFFF,t_70,g_se,x_16

 二、封装indexDB库,

第一步:封装类库

/**
 * 封装的方法以及用法
 * 打开数据库
 */
export function openDB(dbName, storeName, version = 1) {
  return new Promise((resolve, reject) => {
    let indexedDB = window.indexedDB
    let db
    const request = indexedDB.open(dbName, version)
    request.onsuccess = function(event) {
      db = event.target.result // 数据库对象
      resolve(db)
    }
 
    request.onerror = function(event) {
      reject(event)
    }
 
    request.onupgradeneeded = function(event) {
      // 数据库创建或升级的时候会触发
      console.log('onupgradeneeded')
      db = event.target.result // 数据库对象
      let objectStore
      if (!db.objectStoreNames.contains(storeName)) {
        objectStore = db.createObjectStore(storeName, { keyPath: 'id' }) // 创建表
        // objectStore.createIndex('name', 'name', { unique: true }) // 创建索引 可以让你搜索任意字段
      }
    }
  })
}
 
/**
 * 新增数据
 */
export function addData(db, storeName, data) {
  return new Promise((resolve, reject) => {
    let request = db.transaction([storeName], 'readwrite') // 事务对象 指定表格名称和操作模式("只读"或"读写")
      .objectStore(storeName) // 仓库对象
      .add(data)
 
    request.onsuccess = function(event) {
      resolve(event)
    }
 
    request.onerror = function(event) {
      throw new Error(event.target.error)
      reject(event)
    }
  })
}
 
/**
 * 通过主键读取数据
 */
export function getDataByKey(db, storeName, key) {
  return new Promise((resolve, reject) => {
    let transaction = db.transaction([storeName]) // 事务
    let objectStore = transaction.objectStore(storeName) // 仓库对象
    let request = objectStore.get(key)
 
    request.onerror = function(event) {
      reject(event)
    }
 
    request.onsuccess = function(event) {
      resolve(request.result)
    }
  })
}
 
/**
 * 通过游标读取数据
 */
export function cursorGetData(db, storeName) {
  let list = []
  let store = db.transaction(storeName, 'readwrite') // 事务
    .objectStore(storeName) // 仓库对象
  let request = store.openCursor() // 指针对象
  return new Promise((resolve, reject) => {
    request.onsuccess = function(e) {
      let cursor = e.target.result
      if (cursor) {
        // 必须要检查
        list.push(cursor.value)
        cursor.continue() // 遍历了存储对象中的所有内容
      } else {
        resolve(list)
      }
    }
    request.onerror = function(e) {
      reject(e)
    }
  })
}
 
/**
 * 通过索引读取数据
 */
export function getDataByIndex(db, storeName, indexName, indexValue) {
  let store = db.transaction(storeName, 'readwrite').objectStore(storeName)
  let request = store.index(indexName).get(indexValue)
  return new Promise((resolve, reject) => {
    request.onerror = function(e) {
      reject(e)
    }
    request.onsuccess = function(e) {
      resolve(e.target.result)
    }
  })
}
 
/**
 * 通过索引和游标查询记录
 */
export function cursorGetDataByIndex(db, storeName, indexName, indexValue) {
  let list = []
  let store = db.transaction(storeName, 'readwrite').objectStore(storeName) // 仓库对象
  let request = store.index(indexName) // 索引对象
    .openCursor(IDBKeyRange.only(indexValue)) // 指针对象
  return new Promise((resolve, reject) => {
    request.onsuccess = function(e) {
      let cursor = e.target.result
      if (cursor) {
        list.push(cursor.value)
        cursor.continue() // 遍历了存储对象中的所有内容
      } else {
        resolve(list)
      }
    }
    request.onerror = function(ev) {
      reject(ev)
    }
  })
}
 
/**
 * 更新数据
 */
export function updateDB(db, storeName, data) {
  let request = db.transaction([storeName], 'readwrite') // 事务对象
    .objectStore(storeName) // 仓库对象
    .put(data)
 
  return new Promise((resolve, reject) => {
    request.onsuccess = function(ev) {
      resolve(ev)
    }
 
    request.onerror = function(ev) {
      resolve(ev)
    }
  })
}
 
/**
 * 删除数据
 */
export function deleteDB(db, storeName, id) {
  let request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(id)
 
  return new Promise((resolve, reject) => {
    request.onsuccess = function(ev) {
      resolve(ev)
    }
 
    request.onerror = function(ev) {
      resolve(ev)
    }
  })
}
 
/**
 * 删除数据库
 */
export function deleteDBAll(dbName) {
  console.log(dbName)
  let deleteRequest = window.indexedDB.deleteDatabase(dbName)
  return new Promise((resolve, reject) => {
    deleteRequest.onerror = function(event) {
      console.log('删除失败')
    }
    deleteRequest.onsuccess = function(event) {
      console.log('删除成功')
    }
  })
}
 
/**
 * 关闭数据库
 */
export function closeDB(db) {
  db.close()
  console.log('数据库已关闭')
}
 
export default {
  openDB,
  addData,
  getDataByKey,
  cursorGetData,
  getDataByIndex,
  cursorGetDataByIndex,
  updateDB,
  deleteDB,
  deleteDBAll,
  closeDB
}

第二步:使用类库,该库的使用方法如下

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
  <title>Title</title>
  <link href="./favicon.png">
</head>
<body>
</body>
 
注意要加 type="module"
<script type="module">
-->
<script type="module">
  import IndexDB from './IndexDB.js'
 
  (async function() {
 
    const dbName = 'myDB', storeName = 'db_1'
    const db = await IndexDB.openDB(dbName, storeName, 1)
    var data = await IndexDB.addData(db, storeName, {
      id: 111, // 必须且值唯一
      name: '张三',
      age: 18,
      desc: 'helloWord'
    })
    console.log(data)
 
    var data = await IndexDB.getDataByKey(db, storeName, 111)
    console.log(data)
 
    var data = await IndexDB.updateDB(db, storeName, { id: 111, desc: '修改的内容' })
    console.log(data)
 
    var data = await IndexDB.deleteDB(db, storeName, 111)
    console.log(data)
  })()
</script>
</html>

三、使用indexdb第三方类库indexdbwrapper(这种方式需要懂得使用打包工具开发不懂跳过)

/* 下载
 cnpm install --save indexdbwrapper
*/
// 引入
import IndexDBWrapper from 'indexdbwrapper'
// 使用
async function dbTest() {
      const dbName = 'dbName', storeName = 'storeName', version = 1
 
      const db = new IndexDBWrapper(dbName, version, {
        onupgradeneeded(event) {
          const db = event.target.result // 数据库对象
          let objectStore
          if (!db.objectStoreNames.contains(storeName)) {
            objectStore = db.createObjectStore(storeName, { keyPath: 'id' }) // 创建表
            // objectStore.createIndex('createTime', 'createTime', { unique: false }) // 创建索引 可以让你搜索任意字段
          }
        }
      })
      await db.open()
      await db.add(storeName, { id: new Date().getTime(), updateTime: new Date().getTime() })
      console.log(await db.get(storeName, 1639015754840))
      console.log(await db.put(storeName, { id: 1639015754840, put: 'put2' }))
      console.log(await db.get(storeName, 1639015754840))
      console.log(await db.delete(storeName, 1639015754840))
      // console.log(await db.clear(storeName))
}
dbTest()

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MPP 还是主流架构吗

MPP 架构&#xff1a; MPP 架构的产品&#xff1a; Impala ClickHouse Druid Doris 很多 OLAP 引擎都采用了 MPP 架构 批处理系统 - 使用场景分钟级、小时级以上的任务&#xff0c;目前很多大型互联网公司都大规模运行这样的系统&#xff0c;稳定可靠&#xff0c;低成本。…

9.1 功率放大电路概述

在实用电路中&#xff0c;往往要求放大电路的末级&#xff08;即输出级&#xff09;输出一定的功率&#xff0c;以驱动负载。能够向负载提供足够信号功率的放大电路称为功率放大电路&#xff0c;简称功放。从能量控制和转换的角度看&#xff0c;功率放大电路与其它放大电路在本…

c++ qt--信号与槽(二) (第四部分)

c qt–信号与槽(二) &#xff08;第四部分&#xff09; 一.信号与槽的关系 1.一对一 2.一对多 3.多对一 4.多对多 还可以进行传递 信号->信号->槽 一个信号控制多个槽的例子&#xff08;通过水平滑块控制两个组件&#xff09; 1.应用的组件 注意这里最下面的组件…

MongoDB快速上手

MongoDB快速上手 MongoDB用起来-快速上手&集群和安全系列 课程目标&#xff1a; 理解MongoDB的业务场景、熟悉MongoDB的简介、特点和体系结构、数据类型等能够在windows和linux下安装和启动MongoDB、图形化管理界面Compass的安装使用掌握MongoDB基本常用命令实现数据的C…

mysql 、sql server 临时表、表变量、

sql server 临时表 、表变量 mysql 临时表 创建临时表 create temporary table 表名 select 字段 [&#xff0c;字段2…&#xff0c;字段n] from 表

项目解决问题

红外 没接收到红外信号时&#xff0c; 会有杂波干扰 STC单片机 STC的串口要用一个定时器作为波特率发生器 开定时器2需要 开定时器0 1 要ET0 1 ET11打开 串口有时候和定时器有冲突 串口发送函数放定时器中断函数中&#xff0c;时间太少可能会导致一直卡在定时器中AUXR | 0x…

精彩回顾 | 风丘科技亮相2023中国汽车测试及质量监控博览会

2023年8月9-11日&#xff0c;风丘科技携手德国Softing、德国IPETRONIK亮相中国汽车测试及质量监控博览会&#xff08;2023 Testing Expo&#xff09;&#xff0c;为大家呈现了在汽车测试、车辆诊断领域里专业的研发测试工具及创新解决方案&#xff0c;吸引了众多客户驻足洽谈。…

MySQL基础篇(四)

多表查询 概述&#xff1a;多表查询就是多张表之间的查询。 回顾&#xff1a;SELECT * FROM table_name 多表查询 from 后面就得跟多张表。如&#xff1a;select * from emp,dept 笛卡尔积&#xff1a;笛卡尔积在数学中&#xff0c;表示两个集合&#xff0c;集合 A 和集合 B…

解决`idea`中`database`工具查询起别名乱码问题

文章目录 解决idea中database工具查询起别名乱码问题场景复现如何解决方式一 设置编码方式二&#xff1a;修改字体 原因说明 解决idea中database工具查询起别名乱码问题 场景复现 使用Idea做查询的并且起别名出现了中文乱码 如何解决 方式一 设置编码 settings->输入框输…

算法-滑动窗口-串联所有单词的子串

算法-滑动窗口-串联所有单词的子串 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/substring-with-concatenation-of-all-words/ 1.2 题目描述 2 滑动窗口Hash表 2.1 解题思路 构建一个大小为串联子串的总长的滑动窗口为每个words中的子串创建一个hash表, <子…

BTP Integration Suite学习笔记 - (Unit4) Developing with SAP Integration Suite

详细指导还是要看官方文档 4. 云集成管理 4.1 云集成介绍 什么是云集成&#xff1f; 前三章讲了很多内容&#xff0c;但都不是最核心的&#xff0c;通常我们用CPI是让他实现原来PI/PO的功能的&#xff0c;是用来做集成的。这章才刚开始。 云集成有以下几个特性&#xff1a;…

web基础http与apache

一、http相关概念&#xff1a; http概述&#xff1a; HTTP 是一种用作获取诸如 HTML 文档这类资源的协议。它是 Web 上进行任何数据交换的基础&#xff0c;同时&#xff0c;也是一种客户端—服务器&#xff08;client-server&#xff09;协议 为解决"用什么样的网络协…

添加了.gitignore 文件,git status 的时候还是显示修改文件

1. 用IAR 软件编译STM32 工程&#xff0c;IAR 会生成很多中间文件&#xff0c;这些文件是不需要加入到git 版本管理里面的 2. .gitignore 文件位置需要放对应目录才会起作用&#xff0c;递归起作用的 3. 如果 .gitignore文件中指定的文件或目录仍然显示在git status的输出中&a…

考研C语言进阶题库——更新41-50题

目录 41.编写程序要求输出整数a和b若a和b的平方和大于100&#xff0c;则输出a和b的平方和&#xff0c;否则输出a和b的和 42.现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的&#xff1a;第一项是1/1&#xff0c;第二项是是…

RHCE——四、Web服务器(理论篇)

Web服务器 一、Web服务器1、www简介1.1 常见Web服务程序介绍&#xff1a;1.2 服务器主机1.3 主要数据1.4 浏览器 2、网址及HTTP简介2.1 URL2.2 http请求方法:2.3 HTTP协议请求的工作流程&#xff1a; 3、www服务器的类型静态网站动态网站 二、快速安装Apache1、安装2、准备工作…

[oneAPI] 基于BERT预训练模型的SWAG问答任务

[oneAPI] 基于BERT预训练模型的SWAG问答任务 基于Intel DevCloud for oneAPI下的Intel Optimization for PyTorch基于BERT预训练模型的SWAG问答任务数据集下载和描述数据集构建问答选择模型训练 结果参考资料 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d…

nginx代理webSocket链接,webSocket频繁断开重连

一、场景 1、使用nginx代理webSocket链接&#xff0c;消息发送和接收都是正常的&#xff0c;但webSocket链接会频繁断开重连 2、如果不使用nginx代理则一切正常 3、程序没有做webSocket心跳处理 如下图 二、nginx代理配置 upstream cloud_ass {#ip_hash;server 192.168.1.…

计组 | 寻址方式

目录 一、知识点 1.寻址方式什么&#xff1f; 2.根据操作数所在的位置&#xff0c;都有哪些寻址方式&#xff1f; 3.直接寻址 4.立即寻址 5.隐含寻址 6.相对寻址 7.寄存器 8.寄存器-寄存器型&#xff08;RR&#xff09;、寄存器-存储器型&#xff08;RS&#xff09;和…

C语言<自定义类型>结构体、枚举、联合

✨Blog&#xff1a;&#x1f970;不会敲代码的小张:)&#x1f970; &#x1f251;推荐专栏&#xff1a;C语言&#x1f92a;、Cpp&#x1f636;‍&#x1f32b;️、数据结构初阶&#x1f480; &#x1f4bd;座右铭&#xff1a;“記住&#xff0c;每一天都是一個新的開始&#x1…

手写Vue3响应式数据原理

Vue3响应式数据 前言一、proxy是什么&#xff1f;1.1 proxy基本使用 二、实现最基本的reactive函数三、实现基本响应式系统四、完善基本响应式系统4.1 执行每一个副作用函数4.2 实现依赖收集4.2.1 基本实现 4.3 改进桶结构 五、相关面试题1.Object.defineProperty 和 Proxy 的区…