01-IndexedDB-kickoff
IndexedDB详解
简介
IndexedDB是一种在浏览器端存储数据的方式。既然称之为DB,是因为它丰富了客户端的查询方式,并且因为是本地存储,可以有效的减少网络对页面数据的影响。
有了IndexedDB,浏览器可以存储更多的数据,从而丰富了浏览器端的应用类型。
IndexedDB简介
IndexedDB和传统的关系型数据不同的是,它是一个key-value型的数据库。
value可以是复杂的结构体对象,key可以是对象的某些属性值也可以是其他的对象(包括二进制对象)。你可以使用对象中的任何属性做为index,以加快查找。
IndexedDB是自带transaction的,所有的数据库操作都会绑定到特定的事务上,并且这些事务是自动提交了,IndexedDB并不支持手动提交事务。
IndexedDB API大部分都是异步的,在使用异步方法的时候,API不会立马返回要查询的数据,而是返回一个callback。
异步API的本质是向数据库发送一个操作请求,当操作完成的时候,会收到一个DOM event,通过该event,我们会知道操作是否成功,并且获得操作的结果。
IndexedDB是一种 NoSQL 数据库,和关系型数据库不同的是,IndexedDB是面向对象的,它存储的是Javascript对象。
IndexedDB还有一个很重要的特点是其同源策略,每个源都会关联到不同的数据库集合,不同源是不允许访问其他源的数据库,从而保证了IndexedDB的安全性。
IndexedDB的使用
这一节,我们将会以具体的例子来讲解如何使用IndexedDB。
IndexedDB的浏览器支持
不同的浏览器对于IndexedDB有不同的实现,正常来说,我们可以使用window.indexedDB来获取到浏览器的indexedDB对象。但是对于某些浏览器来说,还没有使用标准的window.indexedDB,而是用带前缀的实现。
所以我们在使用过程中通常需要进行判断和转换:
上面我们从window获取了indexedDB,IDBTransaction和IDBKeyRange三个对象。
其中indexedDB表示的是数据库的连接。IDBTransaction表示的是transaction,而IDBKeyRange则是用从数据库的某个特定key range中取出数据。
但是,通常来说带前缀的实现一般都是不稳定的,所以我们通常不建议在正式环境中使用,所以如果不支持标准表达式的话,需要直接报错:
创建IndexedDB
要使用IndexedDB,我们首先需要open it:
open方法返回一个IDBOpenDBRequest对象,同时这是一个异步操作,open操作并不会立马打开数据库或者开启事务,我们可以通过监听request的事件来进行相应的处理。
open方法传入两个参数,第一个参数是数据库的名字,第二个参数是数据库的版本号。
当你创建一个新的数据库或者升级一个现有的数据库版本的时候,将会触发一个onupgradeneeded事件,并在事件中传入IDBVersionChangeEvent,我们可以通过event.target.result来获取到IDBDatabase对象,然后通过这个对象来进行数据库的版本升级操作。如下所示:
注意,这里的版本号是一个整数。如果你传入一个float,那么将会对该float进行取整操作。
有了request,我们可以通过监听onerror或者onsuccess事件来进行相应的处理。
拿到db对象之后,我们可以设置全局的异常处理:
IndexedDB中的table叫做object stores,和关系型数据库中的table一样,object stores中的每一个对象都和一个key相关联,和key相关的有两个概念 key path 和 key generator.
如果存储的是javascript Object对象,那么可以指定该对象中的某一个属性作为key path,那么这个属性将会被作为key。
如果没有指定key path,那么存储的Object可以是任何对象,甚至是基础类型比如数字和String。
而key generator就是key的生成器。
假如我们想要存储这样的数据:
看一下对应的数据库操作是怎么样的:
我们需要在onupgradeneeded事件中处理所有的schema相关的操作。
首先使用db.createObjectStore创建了一个customers的ObjectStore,并且使用了对象的keypath作为key。
除了key之外,我们创建了两个index,以提高查询速度。
最后我们监听transaction.oncomplete事件,并在里面加入存储object的操作。
上面的代码中,我们使用了keyPath作为key。
下面是一个使用key Generator的例子:
indexdb中的CURD
indexedDB的所有操作都需要在事务中,我们看一个开启事务的操作:
上面的例子中使用readwrite来操作customers ObjectStore。
transaction接收两个参数,第一个参数是一个数组,数组中是这个trans中将会处理的ObjectStores,第二个参数是处理的模式。
有了transaction之后,我们可以监听事务的complete和error操作,然后就可以进行add操作了:
上面的例子中,我们使用了add方法,add的前提是数据库中并不存在相同key的对象。除了add方法之外,我们还可以使用put方法,put方法主要用来进行更新操作。
再看一个删除的操作:
现在我们的数据库已经有了数据,我们看下怎么进行查询:
这里,我们直接使用了db.transaction,默认情况下是readonly模式的。
下面是一个更新的例子:
更新我们使用的是put方法。
使用游标cursor
indexedDB支持游标操作,我们可以使用cursor来遍历objectStore的数据:
openCursor可以接受多个参数,第一个参数可以接受key的查询范围,第二个参数用来指定遍历的方向。如果两个参数都为空的话,默认是所有的数据的以升序的顺序遍历。
如果想遍历下一个游标,则可以调用cursor.continue。
我们看一下两个参数的游标使用:
除了openCursor,我们还可以通过使用openKeyCursor来遍历KeyCursor:
除此之外,我们还可以直接通过index来进行查询:
要使用index的前提就是需要在request.onupgradeneeded中创建index。
本文作者:flydean程序那些事
本文链接:www.flydean.com
本文来源:flydean的博客
欢迎关注我的公众号:「程序那些事」最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
最后更新于
这有帮助吗?