indexDB入门到精通

前言
由于开发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.mfbz.cn/a/94936.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WordPress主题Zing V2.2.1/模块化WordPress响应式通用企业商城主题

WordPress主题Zing V2.2.1&#xff0c;模块化WordPress响应式通用企业商城主题。 功能介绍 百度熊掌号文章实时推送、原创保护 多设备支持自适应布局&#xff0c;支持电脑、Pad、手机以及各种浏览器 SEO优化首页、文章、页面、分类均支持自定义标题、关键字和描述 速度优化…

龙芯2K1000LA移植交叉编译环境以及QT

嵌入式大赛结束了&#xff0c;根据这次比赛中记的凌乱的笔记&#xff0c;整理了一份龙芯2K1000LA的环境搭建过程&#xff0c;可能笔记缺少了一部分步骤或者错误&#xff0c;但是大致步骤可以当作参考。 一、交叉编译工具链 下载连接&#xff1a;龙芯 GNU 编译工具链 | 龙芯开…

jq插件:jqgrid和validform的二次封装

做久了vue和react框架项目&#xff0c;偶尔也需要做做原生的项目。不可否认vue的双向绑定机制确实很香&#xff0c;但是也是建立在原生js基础上。所以&#xff0c;只有做更多的原生js项目&#xff0c;才能更加了解vue框架的底层原理。在日常开发中&#xff0c;也会不可避免的会…

cortex-A7核PWM实验--STM32MP157

实验目的&#xff1a;驱动风扇&#xff0c;蜂鸣器&#xff0c;马达进行工作 目录 一&#xff0c;PWM相关概念 有源蜂鸣器和无源蜂鸣器 二&#xff0c;分析电路图&#xff0c;框图 三&#xff0c;分析RCC章节 1&#xff0c;确定总线连接 2&#xff0c;根据总线内容确定基…

SQL语句优化

当表中有百万数据的时候&#xff0c;我们要怎么去查询数据&#xff0c;平时写的sql也许就会很慢了。 SQL的执行顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOIN <right_table> ON <join_condition> WHERE<where_co…

【Luniux】解决Ubuntu外接显示器不显示的问题

Luniux】解决Ubuntu外接显示器不显示的问题 文章目录 Luniux】解决Ubuntu外接显示器不显示的问题1. 检查nvidia显卡驱动是否正常2. 更新驱动3. 检查显示器是否能检测到Reference 1. 检查nvidia显卡驱动是否正常 使用命令行 nvidia-smi来检查显卡驱动是否正常&#xff0c;如果…

gRPC + Spring Boot 编程教程 - piot

在本文中&#xff0c;您将学习如何实现通过 gRPC 通信的 Spring Boot 应用程序。gRPC 是一个现代开源远程过程调用 (RPC) 框架&#xff0c;可以在任何环境中运行。默认情况下&#xff0c;它使用 Google 的 Protocol Buffer 来序列化和反序列化结构化数据。当然&#xff0c;我们…

Ceph入门到精通-LVS基础知识

LB集群: &#xff08;Load Balancing&#xff09;即负载均衡集群,其目的是为了提高访问的并发量及提升服务器的性能&#xff0c;其 实现方式分为硬件方式和软件方式。 硬件实现方式&#xff1a; 常用的有 F5公司的BIG-IP系列、A10公司的AX系列、Citrix公司的 NetScaler系列…

HUT23级训练赛

目录 A - tmn学长的字符串1 B - 帮帮神君先生 C - z学长的猫 D - 这题用来防ak E - 这题考察FFT卷积 F - 这题考察二进制 G - 这题考察高精度 H - 这题考察签到 I - 爱派克斯&#xff0c;启动! J - tmn学长的字符串2 K - 秋奕来买瓜 A - tmn学长的字符串1 思路&#x…

华为OD机试 - VLAN资源池 - 回溯、双指针(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路1、核心思想2、具体解题思路 五、Java算法源码六、效果展示1、输入2、输出 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&…

什么是NetDevOps

NetDevOps 是一种新兴的方法&#xff0c;它结合了 NetOps 和 DevOps 的流程&#xff0c;即将网络自动化集成到开发过程中。NetDevOps 的目标是将虚拟化、自动化和 API 集成到网络基础架构中&#xff0c;并实现开发和运营团队之间的无缝协作。 开发运营&#xff08;DevOps&…

敏捷研发管理软件及敏捷管理流程

Scrum中非常强调公开、透明、直接有效的沟通&#xff0c;这也是“可视化的管理工具”在敏捷开发中如此重要的原因之一。通过“可视化的管理工具”让所有人直观的看到需求&#xff0c;故事&#xff0c;任务之间的流转状态&#xff0c;可以使团队成员更加快速适应敏捷开发流程。 …

JVM知识点(二)

1、G1垃圾收集器 -XX:MaxGCPauseMillis10&#xff0c;G1的参数&#xff0c;表示在任意1s时间内&#xff0c;停顿时间不能超过10ms&#xff1b;G1将堆切分成很多小堆区&#xff08;Region&#xff09;&#xff0c;每一个Region可以是Eden、Survivor或Old区&#xff1b;这些区在…

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询

「前言」文章内容大致是对MySQL复合查询的学习。 「归属专栏」MySQL 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、基本查询回顾二、多表查询三、自连接四、子查询4.1 单行子查询4.2 多行子查询4.3 多列子查询4.4 在from子句中使用子查询 五、合并查询 一、基本查询回顾…

解密算法与数据结构面试:程序员如何应对挑战

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

Windows版本Docker安装详细步骤

文章目录 下载地址安装异常处理docker desktop requires a newer wsl 下载地址 https://desktop.docker.com/win/stable/Docker%20Desktop%20Installer.exe 安装 双击下载的文件Docker Desktop Installer.exe进行安装 点击OK 开始安装 安装完成点击Close and restart&…

电脑不安装软件,怎么将手机文件传输到电脑?

很多人都知道&#xff0c;AirDroid有网页版&#xff08;web.airdroid.com&#xff09;。 想要文件传输&#xff0c;却不想在电脑安装软件时&#xff0c;AirDroid的网页版其实也可以传输文件。 然而&#xff0c;要将文件从手机传输文件到网页端所在的电脑时&#xff0c;如果按…

“惠医通-医院挂号订单平台”

结合已学习过的vue3和TS完成的项目&#xff0c;便于患者对自己想要就诊的科室进行挂号&#xff0c;付款 一&#xff1a;项目简介 前端技术栈 Vue3 TS vue-router Element-ui Axios Pinia 项目架构 二&#xff1a;主要模块 1. axios二次封装 1.1 创建实例 //利用axios.creat…

视频融合平台EasyCVR视频汇聚平台关于小区高空坠物安全实施应用方案设计

近年来&#xff0c;随着我国城市化建设的推进&#xff0c;高楼大厦越来越多&#xff0c;高空坠物导致的伤害也屡见不鲜&#xff0c;严重的影响到人们的生命安全。像在日常生活中一些不起眼的小东西如烟头、鸡蛋、果核、易拉罐&#xff0c;看似伤害不大&#xff0c;但只要降落的…

Go【gin和gorm框架】实现紧急事件登记的接口

简单来说&#xff0c;就是接受前端微信小程序发来的数据保存到数据库&#xff0c;这是我写的第二个接口&#xff0c;相比前一个要稍微简单一些&#xff0c;而且因为前端页面也是我写的&#xff0c;参数类型自然是无缝对接_ 前端页面大概长这个样子 先用apifox模拟发送请求测试…