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

一:什么是indexedDB?

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

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

7b8fff7fc0b7ab9ac958607aaaa3b1be.png

具体操作: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.οnerrοr=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,查询一条记录

按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()

};

}

});

游标查询全部

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()中把数组返回回去。

}

}

}

});

未完待补充

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值