关于使用HTML5提供的indexedDB的一下心得

一:什么是indexedDB?

indexedDB是HTML5实现本地存储一个小型数据库,并且在Chome,IE等主流浏览器已经得到很好的支持,

IndexedDB是为了能够在客户端存储大量的结构化数据,并且使用索引高效检索的API。但是这些API的使用很纠结,就是大多数的API全是异步执行。它存储的数据格式是json对象格式,由键值对表示,像这样: 输入图片说明

具体操作:f12,找resorce,找indexedDB

二:我使用indexedDB的问题

使用indexedDB的时候会出现很多比较纠结的情况,因为它的很多基本操作都是异步执行的,官方文档说提供的有同步的API,但是直到最后也没有找到,再加上js这种弱类型的语言,刚接触的时候是在让我苦不堪言。特在此总结下我在使用indexedDB时遇到的问题和最终的解决方案,希望有用。

三:基本使用

1,建立数据库:

var myDB={
    dbName="testDB",
db=null
        
}
var request=window.indexedDB.open(myDB.dbName);

解释:这个语句表示打开一个名叫testDB的数据库,如果该数据库不存在,会自动创建一个名为textDB的数据库。这个requese提供三个回调函数,分别是onsuccess(),onerror(),onupgrandeneed(). 这三个函数分别在打开或者创建数据库成功,失败,更新时候调用。

requese.onsuccess=function(e){
    console.log("打开数据库成功,db==="+e.target.result);
       myDB.db=e.target.result;
}

这个地方的e.target.result就是已经打开的数据库对象db,接下来的任何操作都要用到这个db,所以最好把这个代码封装成一个函数,用回调函数的方法,直接返回一个db,以便于后来操作。 同理,onerror方法就是在打开数据库失败的时候调用,可以在onerror函数里打印错误信息,例如:

request.onerror=function(e){
    console.log("打开数据库失败,错误信息为:"+e.terget.error.message);
        
}

重要的说一下第三个函数,onupgrandeneed(),这个函数在数据库需要更新的时候调用,比如,第一次创建数据库的时候或者是数据库新添加了objectStore时,(objectStore相当于表的概念)。例如:

request.onupgrandeneed=function(e){
    var objectStore=myDB.db.createObjectStore("objectStore1",{keyPath:"ID"});
      var objectStore2=myDB.db.createObjectStore2("objectStore2",{keyPath:"ID"});   
    //给objectStore2表加一个索引
   objectStore2.creatIndex("timeIndex","Time",{unique:false});



            
}

解释一下:creatObjectStore()函数,用于建一个objectStore,而objectStore的概念相当于在其他数据库中的表的概念。该函数的两个参数分别为(表名称,主键)。

这里说主键并不准确,但是跟主键的概念很像,请原谅我的简单粗暴。 在这里值得注意的就是:存进去的数据,必须有这个keyPath的键,否则会报错,而其他的无所谓,可有可无,看你的需求。如果你要使用索引的话,那么这个索引值得字段也必须有的。

creatIndex()函数的三个参数分别是(索引名称,以哪个字段做索引,是否唯一)

2,使用回调函数获取db对象

 var myDB={
    dbName="testDB",
    db=null  
}

openDB:function(callBack){
var request=window.indexedDB.open(myDB.dbName);
     requese.onsuccess=function(e){
    console.log("打开数据库成功,db==="+e.target.result);
      myDB.db=e.target.result;
     callBack( myDB.db);
}           
}

这里的callBack是一个函数,当调用openDB方法的时候,需要传进来一个函数作为参数。在onsuccess()函数里,调用callBack,把获得到的db对象传给调用openDB的对象。具体使用下边有。

解释一下用这种办法获取db的原因: 因为onsuccess的调用是在打开数据库成功之后,而这个函数是异步调用的,也就是说,你不知道什么时候db是存在的,如果直接return db,得到的会是undefined。而使用js的回调,会很巧妙的避免这个问题。

3,增加一条记录

openDB(function(db){
    var transaction=db.transaction("objectStore1","readwrite");
    var objectStore=transaction.objectStore("objectStore2");
    var value={"ID":001,"Time":2013.01.02};
    var request=objectStore.put(value);
    //这个地方也可以用add,跟put的区别是add不会覆盖如果已经存在的数据,而put会覆盖。
    request.onsuccess=function(e){
        console.log("插入成功");
    }
transaction.oncomplete=function(){
    console.log("这个时候才是真的插入成功了");
        
}
});

这个地方有几个微妙的地方

1,定义的value必须有你建立objectStore的时候定义的keyPath和索引值

2,transaction.oncomplete字面意思是事务提交,顾名思义,就是在定义的这个事务全部执行完成的时候,才会执行的。只有在这个函数执行之后,再去表里查询这条数据,才会有,否则会查不到,哪怕是在onsuccess执行之后马上查询,也是查询不到的。当初为这个问题纠结很久,这跟传统的关系型数据库相差较大。

3,关于事务的定义,如果需要批量插入数据,事务的定义要定义在循环之外,否则会很大程度的影响插入效率。例如

4,要注意transaction的权限问题,readonly代表只读,readwrite代表读写。 默认是readonly

openDB(function(db){
    var transaction=db.transaction("objectStore1","readwrite");
    var objectStore=transaction.objectStore("objectStore2");
for(var i=0;i<1000;i++){
     var value={"ID":i,"Time":2013.01.02};
    var request=objectStore.put(value);
    //这个地方也可以用add,跟put的区别是add不会覆盖如果已经存在的数据,而put会覆盖。
    request.onsuccess=function(e){
        console.log("插入成功");
    }
}
   
transaction.oncomplete=function(){
    console.log("这个时候才是真的插入成功了");
        
}
});

像这样,把transaction定义在for循环外边,1000条数据会秒插入。当初为了省事,把插入直接封装成一个函数,在这个函数里定义事务,会很慢,十几秒才把1000条数据插入完,慢的我怀疑人生。后来改成把transaction也传进来,但是这会导致transaction失效。会报:this transaction is not activited。

4,删除一条记录

openDB(function(db){
   var transaction=db.transaction("objectStore2",'readwrite'); 
            var store=transaction.objectStore("objectStore2"); 
            store.delete(key);
    } 
});
//简单粗暴,不多解释

###5,修改一条记录

openDB(function(db){
   var transaction=db.transaction("objectStore2",'readwrite'); 
            var store=transaction.objectStore("objectStore2"); 
            var request=store.get(key); 
            request.onsuccess=function(e){ 
                var model=e.target.result; 
                model.Time=2015.09.09;
                store.put(model); 
            };
    } 
});
//查出来,修改,再放进去覆盖掉。

###5,查询一条记录

  1. 按keyPath查询
openDB(function(db){
   var transaction=db.transaction("objectStore2",'readonly'); 
            var store=transaction.objectStore("objectStore2"); 
            var request=store.get(key); 
            request.onsuccess=function(e){ 
                var model=e.target.result; 
              //这个地方最好也用回调函数把查到的值返回回去。方法同openDB()
            };
          
    } 
});
  1. 游标查询全部
openDB(function(db){
   var transaction=db.transaction("objectStore2",'readonly'); 
            var array=new Array();
            var store=transaction.objectStore("objectStore2"); 
            var request=store.openCursor();
            request.onsuccess=function(){
                var cursor=e.target.result;
                if(cursor){
                    array.push(cursor.value);
                    cursor.continue();
                }else{
                   // callBack(array);
                   //在这里可以把数组返回回去。同openDB()
                   //也可以在transaction的oncomplete()中把数组返回回去。
                }
            }
          
    } 
});

未完待补充

转载于:https://my.oschina.net/u/2942400/blog/755945

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值