简单介绍
IndexedDb是html5新添加的特性,目地是使本地数据能够持久性,使用户能够在线和离线访问 Web 应用程序。关于HTML5 本地数据持久性存储,除了IndexedDb,还有 localstorage,和 sessionstrorage ,它们均支持使用一个简单的键值对来存储需要的数据,但对大量结构化数据的存储及高效检索却显的无能为力。
异步API
在IndexedDB中的大部分操作并不是我们常用的“调用——返回”的模式,而是“请求——响应”的模式,
比如打开数据库:
1
| var request=window.indexedDB.open('myDB');
|
它的返回值并不是一个IndexedDb对象,而是一个请求体对象–IDBOpenDBRequest,其中包含了需要的IndexedDb对象,以及三个状态处理函数:
1 2 3
| onerror: 请求失败的回调函数 onsuccess:请求成功的回调函数 onupgradeneeded:请求数据库版本变化的回调函数
|
因为是异步执行,所以请求执行完成,并不一定就能在返回的对象中获取到indexedDb对象句柄。为了避免出现错误,需要在回调中做出相应处理。
数据库
创建数据库
说明:
open可以打开或者创建数据库,如果调用的时候,当前数据库已经存在,则会直接打开,如果不存在就会创建。数据库创建的时候,默认版本是1,如果在open的时候有传入这个参数,那么就会修改数据库的版本号,并调用onupgradeneeded这个回调。需要说明的是,不能打开比当前版本低的数据库,会触发onerror。
1 2 3
| request = window.indexedDB.open(name[, version]); or request = window.indexedDB.open(name[, options])
|
参数:
1 2 3
| name:数据库的名称 version:数据库的版本,可选 option:包含版本及持久存储标志的对象,可选
|
返回值:
一个IDBOpenDBRequest对象
实例:
1 2 3
| var request = window.indexedDB.open("toDoList"[, 4]); or: var request = window.indexedDB.open("toDoList"[, {version: 4, storage: "temporary"}]);
|
关闭/删除数据库
说明:
关闭数据库可以直接调用数据库IDBDatabase对象的close方法,删除数据库使用indexedDB对象的deleteDatabase,如下:
1 2
| IDBDatabase.close(); indexedDB.deleteDatabase(name);
|
参数:
实例:
1 2 3 4 5 6 7 8 9
| var DBOpenRequest = window.indexedDB.open("toDoList", 4); DBOpenRequest.onerror = function(event) { }; DBOpenRequest.onsuccess = function(event) { db = DBOpenRequest.result; db.close(); }
|
数据存储对象(数据表)
说明:
IndexedDb中的存储对象,相当于mySql中的数据表,一个数据库中可以创建多张数据表,在IndexedDb中也是一样,一个数据库中可以创建多个存储对象,称之为objectStore。
创建objectStore(数据表)
说明:
使用IDBDatabase对象的createObjectStore方法:
1
| IDBDatabase.createObjectStore(storeName [,"keyPath"] )
|
参数:
1 2
| storeName:存储对象的名字 keyPath:主健名,可选
|
返回值:
返回创建出来的存储对象。
实例:
1
| IDBDatabase.createObjectStore('students',{keyPath:"id"});
|
删除objectStore(数据表)
说明:
使用IDBDatabase对象的deleteObjectStore方法:
1
| IDBDatabase.deleteObjectStore(storeName)
|
参数:
使用事务
说明:
在IndexedDb中对存储对象中的数据所有操作都是基于事务的,事务提供了数据库操作的一个原子集合,对数据进行写入操作,同时也具有中止和提交工具。
事务模式:
1 2 3 4
| 模式 描述 readonly 提供对某个对象存储的只读访问,在查询对象存储时使用。 readwrite 提供对某个对象存储的读取和写入访问权。 versionchange 提供读取和写入访问权来修改对象存储定义,或者创建一个新的对象存储。
|
默认的事务模式为 readonly,可以时刻打开多个 readonly 事务,但一次只能打开一个 readwrite 事务。因此,只有在数据更新时才考虑使用 readwrite 事务,其它情况下只用 readonly 。单独的(不同时打开其它类型事务时)versionchange 事务操作一个数据库或对象存储。可以在 onupgradeneeded 事件处理函数中使用 versionchange 事务用来创建、修改或删除一个对象存储。
创建事务:
使用IDBDatabase中的transaction(storeName,mode)来创建事务。
1
| IDBDatabase.transaction("students");
|
参数:
1 2
| storeName: 数据存储对象的名称,可以是多个,使用数组形式传入,此时模式不能是 readwrite mode: 事务模式,可选,不传入是使用默认值
|
操作数据存储对象(数据表)
关于索引:
对索引的使用使得在web端对大量数据高效检索,快速定位成为可能,这也是IndexedDb与其它html5的web存储的主要区别之一。在indexedDB中有两种索引,一种是自增长的int值;一种是keyPath,是自己指定索引列,常用的索引也是这种。
创建索引
说明:
使用IDBObjectStore的createIndex(objectIndexName, objectKeypath, optionalObjectParameters)来创建:
1
| IDBObjectStore.createIndex(IndexName, Keypath, ObjectParameters)
|
参数:
1 2 3
| indexName:要创建的索引名称 Keypath:创建当前索引使用的存储对象的列记录 ObjectParameters:当前索引可选的属性,为可选参数,其值可以有unique(唯一),multiEntry(可多选),locale
|
实例:
1 2
| var store = IDBDatabase.createObjectStore(sName,{"keyPath":keyName}); store.createIndex("nameIndex","name",{unique:true});
|
删除索引
说明:
使用IDBObjectStore的deleteIndex(objectIndexName)来删除:
1
| IDBObjectStore.deleteIndex(IndexName)
|
参数:
使用索引
说明:
使用IDBObjectStore的index(objectIndexName)来获取索引IDBIndex 对象:
1
| IDBObjectStore.index(IndexName)
|
参数:
1 2 3
| indexName:已存在的索引名称 <span style="color:green">返回值</span>: IDBIndex对象,可以配合游标,检索数据。
|
实例:
1 2 3 4 5 6 7 8 9
| function getDataByIndex(dbobj,storeName){ var transaction=dbobj.transaction(storeName); var store=transaction.objectStore(storeName); var index = store.index("nameIndex"); index.get('张三').onsuccess=function(e){ var student=e.target.result; console.log(student.id); } }
|
关于游标:
IndexedDb的游标,有点类似数组的下标值,可以向前,向后遍历一个数组,甚至可以配合其它条件跳过一些数据。索引跟游标是分不开的,可以在建立索引的时候同时建立游标,然后就可以对数据进行遍历。
创建游标
说明:
使用IDBObjectStore的openCursor(KeyRange, Direction)来创建:
1
| IDBObjectStore.openCursor(KeyRange, Direction)
|
参数:
1 2
| KeyRange:游标的范围对象,即使用该游标时只会返回指定范围内的数据记录,可选,如果不送该值,则返回所有的数据记录。 Direction:游标遍历的方向,可选,如果不送该值,则默认为“next”。
|
KeyRange取值,有以下四种
1 2 3 4 5 6 7 8
| // 只取得当前索引的值为 zhangsan 的数据 IDBKeyRange.only("zhangsan"); // 只取得当前索引的值大于 zhangsan,并且不包括 zhangsan 的数据 IDBKeyRange.lowerBound("zhangsan", true); // 只取得当前索引的值小于 zhangsan,并且包括 zhangsan 的数据 IDBKeyRange.upperBound("zhangsan", false); // 取得当前索引的值介于 zhangsan 和 lisi 之间,并且包括zhangsan,但不包括 lisi 的数据 IDBKeyRange.bound("zhangsan", "lisi", false, true);
|
Direction取值,有以下四种:
1 2 3 4
| IDBCursor.NEXT //顺序循环 IDBCursor.NEXT_NO_DUPLICATE //顺序循环不重复 IDBCursor.PREV //倒序循环 IDBCursor.PREV_NO_DUPLICATE //倒序循环不重复
|
返回值:
返回一个IDBRequest对像,其中包含数据记录的详细情况。
1 2 3 4 5 6
| #### 遍历 类似数组中的自增或自减的操作,IndexedDb中,使用continue(),来进行游标的移动,直到没有数据返回了,返回为undefined结束。 ### 兼容性 现在大部分支持Html5的浏览器都已支持IndexedDb,但在IE11、Edge中只是部分功能支持,Opera暂时不支持,安卓4.4以上全部支持。 通常在使用IndexedDb之前可以加部分前缀:
|
window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB ||window.msIndexedDB ;
window.IDBCursor = window.IDBCursor || window.webkitIDBCursor || window.msIDBCursor ;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction ;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange ;
```
具体可点击此处查询。
总结
IndexedDb是HTML5 的一个重要特性,它实现了本地数据的持久性,使用户能够在线和离线访问 Web 应用程序,也使移动应用程序更灵敏,使用的带宽更少,而且能够在低带宽场景中更高效地工作。在使用过程中,只有将索引,游标等功能相结合才能发挥出它最大的作用。
详细实例
可以点击此处进行在线演示。
所有代码以放在github上,点击此处下载。
本文地址:
http://wsdever.github.io/2016/11/22/20161122/