indexDB入门到精通,indexdb增删查改,封装indexdb类库,indexdb基本使用

目录

前言

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

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

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

  第三步:存入一个helloWorld

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

二、封装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页面

这里需要一个服务器容器打开页面,我这里使用webstrom自带的,路径地址要是有ip地址或者localhost加端口好的格式,

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

 基本的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库,

在实际开发过程中我们并不会直接使用原生的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()

更多相关的indexdbwrapper 相关的教程请看 https://www.npmjs.com/package/indexdbwrapper

未完待续。。。。

 

  • 74
    点赞
  • 235
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
将 Three.js 中的 3D 模型存储到 IndexedDB 中可以通过以下步骤实现: 1. 创建 IndexedDB 数据库:使用 IndexedDB API 创建一个数据库,并在其中创建一个存储对象来存储 3D 模型数据。 2. 将 3D 模型转换为二进制数据:使用 Three.js 提供的 GLTFExporter 将 3D 模型转换为二进制数据。 3. 存储二进制数据:将转换后的二进制数据存储到 IndexedDB 中的存储对象中。 4. 从 IndexedDB 中获取数据:使用 IndexedDB API 获取存储对象中的数据,并使用 Three.js 提供的 GLTFLoader 将二进制数据转换为 3D 模型。 下面是一个示例代码,用于将 Three.js 中的 3D 模型存储到 IndexedDB 中并从 IndexedDB 中获取数据: ```javascript // 创建 IndexedDB 数据库 const request = window.indexedDB.open('3d-models', 1); let db; request.onerror = (event) => { console.log('Database error: ' + event.target.errorCode); }; request.onsuccess = (event) => { db = event.target.result; }; request.onupgradeneeded = (event) => { const db = event.target.result; const objectStore = db.createObjectStore('models', { keyPath: 'id' }); }; // 将 3D 模型转换为二进制数据并存储到 IndexedDB 中 const exporter = new THREE.GLTFExporter(); exporter.parse(scene, (gltf) => { const binaryData = new Blob([gltf], { type: 'application/octet-stream' }); const transaction = db.transaction(['models'], 'readwrite'); const objectStore = transaction.objectStore('models'); const request = objectStore.put({ id: 'my-3d-model', data: binaryData }); request.onerror = (event) => { console.log('Error storing 3D model: ' + event.target.error); }; request.onsuccess = (event) => { console.log('3D model stored successfully'); }; }); // 从 IndexedDB 中获取数据并将二进制数据转换为 3D 模型 const loader = new THREE.GLTFLoader(); const transaction = db.transaction(['models'], 'readonly'); const objectStore = transaction.objectStore('models'); const request = objectStore.get('my-3d-model'); request.onerror = (event) => { console.log('Error retrieving 3D model: ' + event.target.error); }; request.onsuccess = (event) => { const binaryData = event.target.result.data; const reader = new FileReader(); reader.onload = (event) => { const gltfBlob = new Blob([event.target.result], { type: 'application/octet-stream' }); const fileReader = new FileReader(); fileReader.onload = (event) => { const gltf = JSON.parse(event.target.result); loader.parse(gltf, '', (object) => { scene.add(object.scene); }); }; fileReader.readAsText(gltfBlob); }; reader.readAsArrayBuffer(binaryData); }; ``` 需要注意的是,IndexedDB 的 API 使用起来比较复杂,需要注意处理异步操作和错误处理。同时,存储和读取大型的二进制数据可能会影响性能,因此需要根据具体情况进行优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淋雨一直走~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值