关于使用indexedDB的本地存储(3)

我又回来了~昨天好累啊,参加了某公司的实习生招聘面试,是处女面,从昨晚备考,背了一大堆东西,今早五点起来继续备考,面试是今早十一点半在另外一个城市。我跑过去真是又困又累,提前两个小时到,准点面试。然后……吊胃口不说了,初试应该是过了好像,等到最终结果出来无论成功与否我再把这次应聘经历好好整理发表出来。

现在还是继续说indexedDB,这结束篇我们讲索引~

索引是干啥的,我相信大部分人听名字就知道这个是用来定位数据的,更加方便查找

在indexedDB中,有两种索引,一种是自增长的int值,一种是keyPath(自己指定索引列)  ——汉高祖刘邦

看到这张图是不是很亲切,这次我们就好好分析一下与index相关的属性和方法

1、createIndex创建索引,有三个参数

  ①索引名称

  ②索引属性字段名

  ③索引属性名是否唯一

看代码

var objectStore = db.createObjectStore('students', {keyPath: 'number'});

objectStore.createIndex('index_a', 'number', {unique: true});
objectStore.createIndex('index_b', 'name', {unique: false});

看结果图

索引index_b中那个Key(Key path:'name')就是第二个参数,创建很简单吧

2、删除索引

还记得当时我们删除一个objectStore的条件吗,需要在upgradeneeded事件中才可以删除,为什么我提这个,猜对了,删除索引也必须在upgradeneeded中

首先尝试一下在success事件中

request.onsuccess = function(ev){
    var db = ev.target.result;
    alert('这里是success');
    if(db.objectStoreNames.contains('students')){
        var transaction = db.transaction('students');
        var objectStore = transaction.objectStore('students');
        
        objectStore.deleteIndex('index_a');
        alert('删除成功!');
    }    
}

结果报错如图,非常的亲切

修改代码

request.onupgradeneeded = function(ev){
    var db = ev.target.result;

    if(db.objectStoreNames.contains('students')){
        var transaction = db.transaction('students', 'readwrite');
        var objectStore = transaction.objectStore('students');
        
        objectStore.deleteIndex('index_a');
        alert('删除成功!');
    }
}

让我震惊的是居然又报错了,错误如下

看到这个version change让我想到了transaction中第三种模式versionchange,我尝试的试了试

还是报错,我瞬间就迷茫了,不知道该何去何从,去http://www.w3.org/TR/2010/WD-IndexedDB-20100819/查看了一下关于transaction模式,上面说versionchange模式是存在的,开始为什么会出现这样的情况,我很不解,没有调试出来,如果路过大神知道的话希望指点一二,感激不尽

3、查看索引,这个很简单

request.onsuccess = function(ev){
    var db = ev.target.result;
    alert('这里是success');
    if(db.objectStoreNames.contains('students')){
        var transaction = db.transaction('students');
        var objectStore = transaction.objectStore('students');
                    
        console.log(objectStore.index('index_a'));
    }    
}

这样就可以看到index_a的索引了

都是很详细的信息,1~6下面说

4、indexNames和index()区别,相信大部分人看到英文就明白,一个查看objectStore上所有索引,一个是具体的单个索引

代码不贴了,直接上结果

5、是游标,游标是什么,暂时不要管,先跟着我的思路回到3这个index()这个方法的返回结果上来

我标注了1~6,为了区分一下,下面用(1)这样代替

(1)count这个是判断一个索引属性字段名的数量的,如果当时你创建索引的时候{unique: true},那么你得到的result都是1

(2)get()获取到具体的值

request.onsuccess = function(ev){
    var db = ev.target.result;
    if(db.objectStoreNames.contains('students')){

        var transaction = db.transaction('students');
        var objectStore = transaction.objectStore('students');
        
        var index = objectStore.index('index_a');
        console.log(index.get('22'));
    }
}

结果如下

再一次强调注意异步回调

 (3)getKey

我测试了几下,这个方法有一个参数,是索引的key,如果key存在,结果的result就等于key,如果不存在,result就是undefined,那么问题来了,这个方法有什么用,我是没想到……

——————————————————————————————————————————————————————————————————

为什么这里有分割线,因为我还差三个方法没有说,原谅我没有很好地组织好文章的结构,只好在这里重新总结一下之前漏过的东西了

一个是IDBObjectStore中的openCursor(本文第一张图的5)

还有是IDBIndex的openCursor和openKeyCursor(就往前数两张图的4、5)

让我正式的介绍一个新词,游标。作用是什么,是更便捷的去遍历objectStore,看代码~

request.onsuccess = function(ev){
    var db = ev.target.result;
    if(db.objectStoreNames.contains('students')){

        var transaction = db.transaction('students');
        var objectStore = transaction.objectStore('students');
        
        var cursor = objectStore.openCursor(/* 可以给键值 */);

        cursor.onsuccess = function(e){
            console.log(e.target.result);
        }
    }
}

结果如图:

喵了个咪的又来这么多内容,indexedDB别人两篇博文就搞定,我这边三篇都要感觉不够了,这里容许我偷下懒,图就少贴一点啦

注意:openCursor是可以给参数的,参数是具体键值或者游标范围

看到了IDBCursorWithValue那么多玩意一个头两个大,没事我们慢慢分析,首当其中的就是direction,这个东西能不能改,我很好奇,我看了下这个属性的attribute

看起来修改没有问题,不确定又去http://www.w3.org/TR/IndexedDB/#dfn-direction看了下,果然没有问题

然后我华丽丽的尝试,失败……报错如下

我整个人都斯巴达了,感觉很不好,这又是一个未能解决的问题

其他的就比较简单靠谱了

简单翻译一下

advance游标前进次数

continue游标向direction方向前进一位

delete删除当前游标记录

update更新当前记录的值

接下来是最后的内容了!

IDBKeyRange对象控制游标的范围,这篇文章出现红字的地方提到过游标范围。IDBKeyRange如何控制

方法如下,我举个简单的例子

var cursor = objectStore.openCursor(IDBKeyRange.bound('11', '33'));

cursor.onsuccess = function(e){
    var c = e.target.result;
    
    console.log(c.value['name']);
    
    c.continue();

}

结果如下:

成功只出现了三个数据,最后因为得到undefined所以取不到value,原来我偷懒没有判断

——————————————————————————————————————————————————————————————

结尾比较仓促,很抱歉,最后总结一下

indexedDB很强大,异步操作,可以存各种数据类型,代价就是API复杂,想弄清楚的话需要多花点时间

主要就是要理解IDBRequest对象是什么,起什么作用

还有IDBDatabase对象、IDBTransaction对象、IDBObjectStore对象、IDBIndex对象、IDBCursor对象和IDBKeyRange对象这六者的关系是什么

三部曲算是结束了,好多的不足,还留下了未解决的问题,挺失败的,不过也是给自己的一次磨练。

这段时间实在是太忙,不忙了看能不能整理下,把内容更好地表达出来

原文地址:https://www.cnblogs.com/constructor/p/4426297.html