当前位置: 首页 > Web前端 > HTML

IndexedDB入门(翻译)

时间:2023-04-02 21:34:36 HTML

前言:这是一篇翻译(原文)。虽然在《高程3》的第23章对IDB有更详细的介绍,但是有点过时了。这篇文章基本上总结了IDB的简单性。知识点,如果需要更详细的了解,可以参考IDB标准。简介HTML5提供的API包括IndexedDBAPI。与WebStorageAPI以键值对的形式在客户端存储数据相比,IDB是一个更加成熟的索引数据库。通过使用IDB,可以更好地构建离线Web应用程序,并且通过将数据存储在浏览器而不是服务器端,减少了服务器与浏览器之间的交互次数并提高了性能。本文主要介绍IDBAPI的基本概念。1)背景:什么是美洲开发银行?IDBAPI来源于浏览器自身的索引数据库,其中包含简单值和对象的记录。每条记录包含键名和对应的值,可以是对象或原始数据类型。IDBAPI有两种形式:同步或异步。通常,使用异步API。IDBAPI是通过window.indexedDB对象实现的。该API在各大浏览器中的支持形式并不统一,一般使用浏览器的前缀来区分。因此,为了实现跨浏览器的兼容,最好在使用IDBAPI之前声明:varindexedDB=window.indexedDB||窗口.webkitIndexedDB||窗口.mozIndexedDB||窗口.msIndexedDB;2)使用IDB前创建数据库需要创建一个数据库。由于数据库工作在异步模式,调用open()方法会返回一个IDBRequest对象,通过它可以绑定成功或错误的事件处理器。下面是一个例子:vardb;varrequest=indexedDB.open("TestDatabase");request.onerror=function(evt){console.log("Databaseerrorcode:"+evt.target.errorCode);};请求.onsuccess=function(evt){db=request.result;};在上面的示例中,调用open()创建一个名为TestDatabase的IDB数据库。然后将onerror和onsuccess事件处理程序绑定到返回的IDBRequest对象。在onsuccess回调函数中,可以通过IDBRequest对象的result属性获取数据库对象,以备后用。其实open()函数中包含的第二个参数并没有明确列出,第二个参数一般是数据库版本号。此参数用于更改数据库版本。如果数据库版本低于参数指示的版本,upgradeneeded事件将被触发,数据库结构将在其事件处理程序中更改。更改版本号是更改数据库结构的唯一方法。3)创建对象存储空间IDB数据库可以包含一对对象存储空间,对象存储空间类似于关系数据库(如MySQL)中的表。您可以使用IDBRequest对象的createObjectStore()方法来创建对象空间。该方法包含两个参数。第一个参数是对象空间的名称,另一个是选项对象,包括keyPath属性和keyGenerator值。keyPath属性是空间中要保存的对象。对象的属性,这个属性会作为存储空间的key。如果对象中没有具有确切名称的keyPath属性,则可以使用autoIncrement作为keyGeneraotr。autoIncrement可以表示任何对象属性。对象存储空间可以有一个用于数据检索的索引,索引可以通过对象存储空间的createIndex()创建,有三个参数:索引名、放置索引的属性名、选项对象。以下是在未分级事件处理程序中创建对象存储的示例:varpeopleData=[{name:"JohnDow",email:"john@company.com"},{name:"DonDow",email:"don@company.com"}];functioninitDb(){varrequest=indexedDB.open("PeopleDB",1);request.onsuccess=function(evt){db=request.result;};request.onerror=function(evt){console.log("IndexedDB错误:"+evt.target.errorCode);};request.onupgradeneeded=function(evt){varobjectStore=evt.currentTarget.result.createObjectStore("people",{keyPath:"id",autoIncrement:true});objectStore.createIndex("名称","名称",{unique:false});objectStore.createIndex("email","email",{unique:true});for(iinpeopleData){objectStore.add(peopleData[i]);}};}上面的例子有如下效果:1)ongradeneeded在Onsuccess回调之前动作,可以通过evt.currentTarget.result访问新建的数据库2)对象中不存在keyPath属性“id”,所以使用autoincrement生成自增keyGenerator。3)创建索引时,可以使用unique来限制索引值的唯一性。4)对象存储空间的add()或put()方法可以添加数据。4)检索数据——创建事务当创建对象存储空间并添加数据时,自然需要访问数据。访问数据是通过IDBTransaction对象,它与浏览器不兼容,因此需要跨浏览器声明:varIDBTransaction=window.IDBTransaction||window.webkitIDBTransaction;这个IDBTransaction对象有三种模式:只读、读/写和快照。通常,事务默认为可读模式。获取到交易的索引后,可以通过objectStore()方法访问具体的存储空间,传入存储空间的名字,然后可以通过get()/add()/put()/delete()/clear()方法来检索、添加和删除数据。事务处理是异步响应,所以返回的是request对象,onerror、onsuccess、oncomplete事件处理器可以绑定到这个request对象上。vartransaction=db.transaction("people",IDBTransaction.READ_WRITE);varobjectStore=transaction.objectStore("people");varrequest=objectStore.add({name:name,email:email});request.onsuccess=function(evt){//添加成功后做一些事情};5)取回数据——游标可以通过事务的get()方法取回数据,但这需要你提前知道数据的keyPath。此外,还可以通过游标检索数据,使用openCursor()方法在事务指定的对象存储空间上创建游标。此方法还返回一个请求对象,该对象可以绑定到onerror或onsuccess。在onsuccess事件处理器中,通过event.target.result获取存储空间中的下一个对象。当结果集中有下一项时,IDBCursor的实例将保存在此属性中。当没有下一项时,该属性的值为空。IDBCursor的实例具有以下属性。a)direction:数值,表示光标移动的方向。默认为IDBCursor.NEXT(0),表示下一项。IDBCursor.NEXT_NO_DUPLICATE(1)表示下一个唯一项,DBCursor.PREV(2)表示上一个项,IDBCursor.PREV_NO_DUPLICATE表示上一个唯一项。b)key:对象的key。c)值:实际对象。d)primaryKey:游标使用的键。可能是对象键或索引键。默认情况下,每个游标只发起一次请求,因此需要移动游标遍历存储空间。这依赖于以下方法:a)continue(key):移动到结果集中的下一项。参数key是可选的,如果不指定该参数,光标会移动到下一项;如果指定了该参数,则光标将移动到指定键的位置。b)advance(count):向前移动count指定的项目数。这两种方法都会导致游标使用相同的请求,因此也可以重用相同的onsuccess和onerror事件处理程序。一个例子:vartransaction=db.transaction("people",IDBTransaction.READ_WRITE);varobjectStore=transaction.objectStore("people");varrequest=objectStore.openCursor();request.onsuccess=function(evt){varcursor=evt.target.result;if(cursor){output.textContent+="id:"+cursor.key+"is"+cursor.value.name+"";游标.continue();}else{console.log("没有更多条目!");}};上面的例子在名为people的对象存储空间上创建了一个事务,然后通过openCursor()在存储空间上创建了一个游标,并在返回的请求对象上调用了evt。target.result获取对象实例,然后通过对象实例的key和value属性填充DIV命名输出。最后遍历continue()方法。6)IDB和webstorage的比较当需要存储少量键值对数据时,webstorage比IDB更适合;但是当需要存储的数据比较多,需要快速检索的时候,IDB比较合适。两者是相辅相成的关系。IDB标准可以参考这个。