![6757287de5a4a88d3251f684f1c7a179.png](https://i-blog.csdnimg.cn/blog_migrate/1757a76c4f173d167229e975632ae892.jpeg)
关于IndexedDB的基本概念和用法本文就不再叙述了,网络上很多相关内容,推荐MDN的使用说明:https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API/Using_IndexedDB
本文主要讲一下查询和升级版本的相关内容
查询
在IndexedDB里,做查询其实很麻烦,它有如下特点:
- 不支持模糊查询
- 不支持分页
- 关键字查询需先创建索引,包括多条件
应用示例
1. 查询指定分类下所有的数据并按创建时间排序
let objectStore = db.transaction('StoreName').objectStore('StoreName');
let request = objectStore.index(createTime).openCursor(category, 'next');
request.onsuccess = function(event) {};
首先,创建时间createTime
是一个索引,因此使用objectStore.index(createTime)
来指定它,之后openCursor
的第二个参数next
,将作用于它。
当所有数据使用的索引值都相同时,排序将会作用于主键。因此,想要满足指定分类同时以创建时间排序,这样显然是不行的。只能自己处理,如:
request.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
result.push(cursor.value);
cursor.continue();
} else {
result.sort(function(a, b) {
if (order == 'prev') {
return -(a.createTime - b.createTime);
} else {
return a.createTime - b.createTime;
}
});
}
}
其次,openCursor
的第一个参数是游标范围,这里使用category
,即指定范围为对应的分类。
最后,顺序有4个值:next
, nextunique
, prev
, prevunique
2. 模糊查询
因为IndexedDB并不支持模糊查询,所以,只能在结果中自行判断,可以简单的使用indexOf
来进行,如:
request.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
if (searchKey && cursor.value.title.indexOf(searchKey) !== -1) {
result.push(cursor.value);
}
cursor.continue();
}
}
升级版本
IndexedDB只有DB, Store, Index的概念,它的存储本身是key value形式,没有字段的概念,所以就没有更新字段的情况,只需要操作Store和Index。字段在创建或更新数据时任意添加。
DB有version,它在打开DB时可以指定,如:
let request = indexedDB.open("dbName", dbVersion);
dbVersion是数字,如果不指定,默认为1,open方法一旦成功,DB则已创建。创建Store和Index会在事件request.onupgradeneeded
里进行。
onupgradeneeded
事件会在两种情况下被触发:
- 创建DB后,即首先执行
indexedDB.open()
函数后 - 升级版本号后,即dbVersion增加
所以,只要需要增加Store或调整Index时,我们就可以增加版本号来触发onupgradeneeded
事件的执行,然后在其里面操作Store和Index。如:
request.onupgradeneeded = function(event) {
db = event.target.result;
if (!db.objectStoreNames.contains('StoreName')) {
let objectStore = db.createObjectStore('StoreName', {autoIncrement: true});
objectStore.createIndex('indexName', 'indexPath', {unique: true});
} else {
objectStore.createIndex('newIndexName', 'newIndexPath', {unique: true});
}
}
这里先判断了Store是否存在,如果在存在的情况下创建会抛出异常。
应用在多窗口被打开时升级版本
这个问题很明显,如果有多个窗口都运行着应用,当升级版本的代码更新后,重载其中一个窗口,那另一个窗口仍然是打开着旧的版本,显然不太正常。所以IndexedDB提供了一个事件(onblocked
)用于确认其它窗口是否关闭或重载。因此:
request.onblocked = function(event) {
alert('请关闭其它打开应用的窗口');
}
在其它窗口关闭后,onupgradeneeded
事件才会被触发。
小结
IndexedDB很方便,但限制还是很多,如果应用关系比较复杂,它并不是一个理想的选择,有时候甚至还不如localStorage,但聊胜于无。