思悟博客
  • 首页
  • 分类
    • 随笔
    • WEB开发
    • 软件及系统
    • 杂类
  • 关于本站
  • 友情链接
    • Dxoca's blog
    • Noahの梦想
爱好、实践、创新
  1. 首页
  2. 杂类
  3. 正文

IndexedDB简介与使用教程

2019年11月18日 1825点热度 0人点赞 0条评论

IndexDB简介


IndexedDB是一个事务型数据库系统,类似于基于SQL的RDBMS。 然而,不像RDBMS使用固定列表,IndexedDB是一个基于JavaScript的面向对象的数据库。 IndexedDB允许您存储和检索用键索引的对象;可以存储结构化克隆算法支持的任何对象。 您只需要指定数据库模式,打开与数据库的连接,然后检索和更新一系列事务。

  • 阅读更多关于 IndexedDB背后的概念。
  • 从使用IndexedDB指南的第一准则中学习异步使用IndexedDB。
  • 联合使用IndexedDB储存离线数据和Service Workers储存离线资源,其简述请查看Service Workers制作离线PWAs。

注意: 正如大多数的web储存解决方案一样,IndexedDB也遵守同源策略。 因此当你在某个域名下操作储存数据的时候,你不能操作其他域名下的数据。

储存限制和回收标准

有许多Web技术在客户端(即本地磁盘)存储各种数据。IndexedDB是最常见的一个。浏览器计算分配给Web数据存储的空间以及达到该限制时要删除的内容的过程并不简单,并且在浏览器之间有所不同。浏览器存储限制和回收标准尝试解释这是如何工作的,至少在火狐的情况下是如此。 使用IndexedDB,你可以使用一个key作为索引进行存储或者获取数据。 你可以在事务(transaction)中完成对数据的修改。

indexedDB不使用结构化查询语言(SQL)。它通过索引(index)所产生的指针(cursor)来完成查询操作,从而使你可以迭代遍历到结果集合。如果你不熟悉NoSQL系统,可以参考维基百科相关文章。

名词解释


数据库(database)

一个信息库,通常包含一个或多个 object stores. 每个数据库必须包含以下内容:
名字(Name):它标识了一个特定源中的数据库,并且在数据库的整个生命周期内保持不变。  此名字可以为任意字符串值(包括空字符串)。
当前版本(version):当一个数据库首次创建时,它的 version 为1,除非另外指定. 每个数据库在任意时刻只能有一个 version。

对象仓库(object store)

数据在数据库中存储的方式, 数据以键值对形式被对象仓库永久持有。对象仓库中的的数据以 keys 升序排列。

每一个对象仓库在同一个数据库中必须有唯一的名字。对象存储可以有一个 key generator 和一个 key path。如果对象仓库有 key path,则使用 in-line keys; 否则使用 out-of-line keys。

关于对象仓库的详细文档,请参考 IDBObjectStore 或者 IDBObjectStoreSync。

数据库连接(database connection)

通过打开数据库创建的操作。一个给定的数据库可以同时拥有多个连接。

事务(transaction)

在一个特定的数据库上,一组具备原子性和持久性的数据访问和数据修改的操作。它是你与数据库交互的方式。并且,任何对于数据库中的数据读和修改的操作只能在事务中进行。

一个数据库连接可以拥有多个与之关联的事务,只要进行写操作事务的作用域不相互重合。事务的作用域在事务被创建时就被确定,指定事务能够进行交互的对象仓库(object store),作用域一旦被确定就会在整个生命周期中保持不变。举个例子,如果一个数据库连接已经有了一个进行写操作的事务,其作用域覆盖 flyingMonkey 对象仓库,你可以开启新的事务其作用于 unicornCentaur 和 unicornPegasus 对象仓库。对于读操作的事务,你可以同时拥有多个,即使他们有重叠的作用域。

事务被期望拥有较短的生命周期,所以浏览器会终止一个消耗时间过长的事务,为了释放存储资源,运行过久的事务会被锁定。你可以中断一个事务,来回滚事务中对数据库进行的操作。并且你甚至不需要等待事务开始或激活就可以中断它。

事务有三种模式:读写、只读和版本变更。创建和删除对象仓库(object store)的唯一方法就是通过调用版本变更事务。了解更多关于事务类型的内容,请参考 IndexedDB。

因为所有的事情都在事务中发生,所以它是 IndexedDB 中非常重要的一个概念。了解更多关于事务,尤其是关于它和版本控制的关联,查看 IDBTransaction 中的参考文档。关于同步接口的文档,查看 IDBTransactionSync。

使用教程


打开数据库

let db
const DBOpenRequest = window.indexedDB.open(dbName, version)
// 如果数据库打开失败
  DBOpenRequest.onerror = () => {
    console.log('数据库打开异常')
  }
  
  DBOpenRequest.onsuccess = () => {        
    // 存储数据结果
    db = DBOpenRequest.result;
  }

创建object store(数据表)信息

DBOpenRequest.onupgradeneeded = (event) => {
    const db = event.target.result;
    
    db.onerror = function() {
      console.log('数据库打开失败');
    };
    
    // 创建一个数据库存储对象
    const objectStore = db.createObjectStore(dbName, { 
      keyPath: 'id'
    });
    
    objectStore.createIndex('id', 'id', {
      unique: true    
    })
};

这个示例中创建了in-line keys的object store,要求所有存储的数据中都要含有id字段,并且以此创建索引,方便后续针对此字段的查找。

createObjectStore的第二个参数即可指定in-line keys中的keyPath

objectStore.createIndex的第一个参数是存储结构object store的key值,第二个字段是存储结构中的key字段对应的要存储的数据对象中的属性值

也可以创建out-of-line keys的object store

// 使用自动生成的递增数字作为键值
const objectStore = db.createObjectStore(dbName, { autoIncrement: true });

objectStore.createIndex('id', 'id', {
  unique: true    
})

增加/更新记录

有add接口,在明确能区分是增加还是更新操作时,建议增加用add接口与,更新用put接口,以提高性能。

但是有些场景是无法区分是增加或者是更新操作的,譬如某个操作后需要更新数据,但是并不知道这条数据之前是否已经存在,那么都使用put接口即可,put接口在没有记录是会增加,存在记录时则更新

const transaction = this.db.transaction([dbName], "readwrite")
// 打开已经存储的数据对象
const objectStore = transaction.objectStore(dbName)
// 添加到数据对象中
const objectStoreRequest = objectStore.put(value)  // 或者使用objectStore.add(value)   
objectStoreRequest.onsuccess = () => {
  resolve()
}
objectStoreRequest.onerror = (err) => {
  console.error(`从数据库读取${key}异常`,err)
  reject()
}

注意:如果创建的表为out-of-line keys类型的object store,那么put()方法中的value不为单参数的“{}”对象形式,而是put(值,键)的形式。

查询记录

查询记录需要使用cursor, cursor类似一个指针,在数据记录中一条条移动遍历出每条记录

let recordList = []
const objectStore = db.transaction(dbName).objectStore(dbName);
objectStore.openCursor().onsuccess = function(event) {
      var cursor = event.target.result;
      // 如果没有遍历完,继续下面的逻辑
      if (cursor) {
          recordList.push(cursor.value);            
          // 继续下一个游标项
          cursor.continue();
      // 如果全部遍历完毕
      } else {
          console.log('存储的数据为',JSON.stringify(recordList))
      }
  }

删除记录

const transaction = db.transaction([dbName], "readwrite")
// 打开已经存储的数据对象
const objectStore = transaction.objectStore(dbName)
// 添加到数据对象中
const objectStoreRequest = objectStore.delete(id)  
objectStoreRequest.onsuccess = () => {
    console.log(`删除${id}成功`)
}
objectStoreRequest.onerror = (err) => {
  console.error(`从数据库删除${id}异常`, err)
}

参考资料


http://echizen.github.io/tech/2018/06-23-indexdb

教程及介绍

http://www.softwhy.com/article-10254-1.html

in-line key与out-in-line key实例

标签: IndexedDB js
最后更新:2019年11月18日
chao

chao

保持求知的状态,每天一点小进步。

点赞
< 上一篇
下一篇 >

期待你的神评呦~

avatar
This comment form is under antispam protection
avatar
This comment form is under antispam protection
  订阅  
提醒
用户您好!请先登录!
登录 注册
标签聚合
对象 代理 js 教程 object Linux this PHP
最新 热点 随机
最新 热点 随机
群晖 GitServer用户为空的解决办法 压缩包处理软件Bandizip破解版下载 宝塔面板安装PHP-Memcached插件失败解决办法 Bing 图片API AdGuard-轻量级的全平台广告过滤工具 Microsoft Wi-Fi Direct Virtual关闭方法 双显卡OBS无图像解决办法(包含集显运行依旧无图像办法) 免费游戏加速器推荐--蓝泡
iOS 12完美越狱? 来见识一下什么是真正的iOS虚拟机Corellium! 你不懂JS: this 与对象原型 -附录A 前端基础进阶(九):详解面向对象、构造函数、原型与原型链 双显卡OBS无图像解决办法(包含集显运行依旧无图像办法) 前端基础进阶(八):深入详解函数的柯里化 div自适应水平垂直居中的方法 DOM系列:浏览器与DOM 你不懂JS: this 与对象原型 -第三章
下面内容为广告
2020年一月
一 二 三 四 五 六 日
 1234
567891011
12131415161718
19202122232425
262728293031  
« 12月    

COPYRIGHT © 2020 思悟博客. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

wpDiscuz
登录
注册|忘记密码?