深入解析HTML5中的IndexedDB索引数据库,前端的数据库

前面一个的数据库:IndexedDB入门

2014/12/27 · 未分类 · IndexedDB

本文由 伯乐在线 –
cucr
翻译,黄利民
校稿。未经许可,幸免转发!
克罗地亚语出处:www.codemag.com。迎接参预翻译组。

应用程序必要多少。对绝大许多Web应用程序来讲,数据在劳动器端组织和保管,顾客端通过互联网恳求获取。随着浏览器变得更其有本领,因而可挑选在浏览器存款和储蓄和决定应用程序数据。

本文向你介绍名字为IndexedDB的浏览器端文档数据库。使用lndexedDB,你能够透过惯于在服务器端数据库大约等同的措施创造、读取、更新和删除多量的记录。请使用本文中可职业的代码版本去体会,完整的源代码能够经过GitHub库找到。

读到本学科的尾声时,你将熟识IndexedDB的基本概念以及哪些促成贰个运用IndexedDB奉行总体的CRUD操作的模块化JavaScript应用程序。让我们略微亲呢IndexedDB并开头吧。

什么是IndexedDB

相似的话,有三种差异类型的数据库:关系型和文书档案型(也堪称NoSQL或对象)。关周详据库如SQL
Server,MySQL,Oracle的多寡存款和储蓄在表中。文书档案数据库如MongoDB,CouchDB,Redis将数据集作为个人对象存款和储蓄。IndexedDB是叁个文档数据库,它在完全内停放浏览器中的三个沙盒情形中(强制依据(浏览器)同源战略)。图1出示了IndexedDB的数码,显示了数据库的布局

图片 1

图1:开采者工具查看多少个object
store

成套的IndexedDB API请参见完整文书档案

深远深入分析HTML5中的IndexedDB索引数据库,html5indexeddb

这篇小说首要介绍了深切解析HTML5中的IndexedDB索引数据库,包括事务锁等基本功用的连带应用示例,要求的朋友能够参照他事他说加以考察下

介绍 IndexedDB是HTML5 WEB数据库,允许HTML5
WEB应用在客户浏览器端存储数据。对于使用来讲IndexedDB特别庞大、有用,能够在客商端的chrome,IE,Firefox等WEB浏览器中存款和储蓄多量多少,上面简要介绍一下IndexedDB的基本概念。
 
什么是IndexedDB IndexedDB,HTML5新的数据存储,可以在客户端存款和储蓄、操作数据,能够使应用加载地越来越快,更加好地响应。它差别于关系型数据库,具备数据表、记录。它影响着大家统一计划和创办应用程序的法子。IndexedDB
成立有数据类型和简单的JavaScript长久对象的object,每一个object可以有目录,使其一蹴而就地询问和遍历整个集结。本文为你提供了什么样在Web应用程序中利用IndexedDB的兢兢业业事例。
 
开始 咱俩要求在施行前富含下前面置代码

JavaScript
Code复制内容到剪贴板

  1. var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
      
  2.     
  3. //prefixes of window.IDB objects   
  4. var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
      
  5. var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange
      
  6.     
  7. if (!indexedDB) {   
  8. alert(“Your browser doesn’t support a stable version of IndexedDB.”)
      
  9. }  

 
打开IndexedDB 在创造数据库在此之前,大家率先必要为数据库创设数量,假若我们有如下的客户消息:

JavaScript
Code复制内容到剪贴板

  1. var userData = [   
  2. { id: “1”, name: “Tapas”, age: 33, email: “[email protected]” },
      
  3. { id: “2”, name: “Bidulata”, age: 55, email: “[email protected]” }
      
  4. ];  

方今我们必要用open()方法展开大家的数据库:

JavaScript
Code复制内容到剪贴板

  1. var db;   
  2. var request = indexedDB.open(“databaseName”, 1);   
  3.     
  4. request.onerror = function(e) {   
  5. console.log(“error: “, e);   
  6. };   
  7.     
  8. request.onsuccess = function(e) {   
  9. db = request.result;   
  10. console.log(“success: “+ db);   
  11. };   
  12. request.onupgradeneeded = function(e) {   
  13.     
  14. }  

如上所示,大家曾经展开了名称叫”databaseName”,钦命版本号的数据库,open()方法有八个参数:
1.第三个参数是数据库名称,它会检查评定名叫”databaseName”的数据库是还是不是已经存在,借使存在则张开它,不然创设新的数据库。
2.次之个参数是数据库的版本,用于客商更新数据库结构。
 
onSuccess处理 发生成功事件时“onSuccess”被触发,假使全体成功的呼吁都在此管理,大家能够由此赋值给db变量保存诉求的结果供之后使用。
 
onerror的处理程序 产生错误事件时“onerror”被触发,假如展开数据库的进度中倒闭。
 
Onupgradeneeded管理程序 举例你想翻新数据库(创建,删除或修改数据库),那么您无法不完毕onupgradeneeded管理程序,使你可以在数据库中做另外改造。
在“onupgradeneeded”管理程序中是足以改造数据库的结构的独一地点。
 
创设和拉长数据到表:
IndexedDB使用对象存储来积累数据,并不是经过表。
每当二个值存款和储蓄在对象存款和储蓄中,它与一个键相关联。
它同意大家创设的任何对象存款和储蓄索引。
索引允许我们访谈存款和储蓄在目的存款和储蓄中的值。
上面包车型客车代码展现了怎么创立对象存款和储蓄并插入预先图谋好的数码:

JavaScript
Code复制内容到剪贴板

  1. request.onupgradeneeded = function(event) {   
  2. var objectStore = event.target.result.createObjectStore(“users”, {keyPath: “id”});
      
  3. for (var i in userData) {   
  4. objectStore.add(userData[i]);    
  5. }   
  6. }  

大家选择createObjectStore()方法创设多少个指标存款和储蓄。 此方法接受五个参数:

  • 储存的称呼和参数对象。
    在此处,大家有三个名称为”users”的靶子存款和储蓄,并定义了keyPath,这是目的独一性的习性。
    在此地,大家应用“id”作为keyPath,那一个值在对象存储中是独一的,大家必需确认保障该“ID”的质量在对象存储中的每种对象中留存。
    一旦创建了目的存款和储蓄,大家得以起初使用for循环加多数据进去。
     
    手动将数据拉长到表:
    咱俩得以手动增多额外的数码到数据库中。

JavaScript
Code复制内容到剪贴板

  1. function Add() {   
  2. var request = db.transaction([“users”], “readwrite”).objectStore(“users”)
      
  3. .add({ id: “3”, name: “Gautam”, age: 30, email: “[email protected]” });
      
  4.     
  5. request.onsuccess = function(e) {   
  6. alert(“Gautam has been added to the database.”);   
  7. };   
  8.     
  9. request.onerror = function(e) {   
  10. alert(“Unable to add the information.”);    
  11. }   
  12.     
  13. }  

前边大家在数据库中做另外的CRUD操作(读,写,修改),必需接纳工作。
该transaction()方法是用来钦命大家想要举办事务管理的对象存款和储蓄。
transaction()方法接受3个参数(第贰个和第多个是可选的)。
第二个是大家要管理的指标存储的列表,第一个钦定大家是或不是要只读/读写,第七个是本子变化。
 
从表中读取数据 get()方法用于从指标存款和储蓄中搜寻数据。
大家事先曾经安装对象的id作为的keyPath,所以get()方法将追寻具备一样id值的对象。
下边包车型客车代码将回来大家命名叫“Bidulata”的目的:

JavaScript
Code复制内容到剪贴板

  1. function Read() {   
  2. var objectStore = db.transaction([“users”]).objectStore(“users”);
      
  3. var request = objectStore.get(“2”);   
  4. request.onerror = function(event) {   
  5. alert(“Unable to retrieve data from database!”);   
  6. };   
  7. request.onsuccess = function(event) {    
  8. if(request.result) {   
  9. alert(“Name: ” + request.result.name + “, Age: ” + request.result.age + “, Email: ” + request.result.email);
      
  10. } else {   
  11. alert(“Bidulata couldn’t be found in your database!”);    
  12. }   
  13. };   
  14. }  

 
从表中读取全数数据
下边的法子搜索表中的所有数据。
这里大家接纳游标来索求对象存款和储蓄中的全部数据:

JavaScript
Code复制内容到剪贴板

  1. function ReadAll() {   
  2. var objectStore = db.transaction(“users”).objectStore(“users”); 
      
  3. var req = objectStore.openCursor();   
  4. req.onsuccess = function(event) {   
  5. db.close();   
  6. var res = event.target.result;   
  7. if (res) {   
  8. alert(“Key ” + res.key + ” is ” + res.value.name + “, Age: ” + res.value.age + “, Email: ” + res.value.email);
      
  9. res.continue();   
  10. }   
  11. };   
  12. req.onerror = function (e) {   
  13. console.log(“Error Getting: “, e);   
  14. };    
  15. }  

该openCursor()用于遍历数据库中的多个记录。
在continue()函数中一连读取下一条记下。
删去表中的记录 下边包车型客车主意从目的中去除记录。

JavaScript
Code复制内容到剪贴板

  1. function Remove() {    
  2. var request = db.transaction([“users”], “readwrite”).objectStore(“users”).delete(“1”);
      
  3. request.onsuccess = function(event) {   
  4. alert(“Tapas’s entry has been removed from your database.”);   
  5. };   
  6. }  

大家要将目的的keyPath作为参数字传送递给delete()方法。
 
末段代码
下边包车型客车办法从目的源中删除一条记下:

JavaScript
Code复制内容到剪贴板

  1. <!DOCTYPE html>  
  2. <head>  
  3. <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />  
  4. <title>IndexedDB</title>  
  5. <script type=”text/javascript”>  
  6. var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
      
  7.     
  8. //prefixes of window.IDB objects   
  9. var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
      
  10. var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange
      
  11.     
  12. if (!indexedDB) {   
  13. alert(“Your browser doesn’t support a stable version of IndexedDB.”)
      
  14. }   
  15. var customerData = [   
  16. { id: “1”, name: “Tapas”, age: 33, email: “[email protected]” },
      
  17. { id: “2”, name: “Bidulata”, age: 55, email: “[email protected]” }
      
  18. ];   
  19. var db;   
  20. var request = indexedDB.open(“newDatabase”, 1);   
  21.     
  22. request.onerror = function(e) {   
  23. console.log(“error: “, e);   
  24. };   
  25.     
  26. request.onsuccess = function(e) {   
  27. db = request.result;   
  28. console.log(“success: “+ db);   
  29. };   
  30.     
  31. request.onupgradeneeded = function(event) {   
  32.     
  33. }   
  34. request.onupgradeneeded = function(event) {   
  35. var objectStore = event.target.result.createObjectStore(“users”, {keyPath: “id”});
      
  36. for (var i in userData) {   
  37. objectStore.add(userData[i]);    
  38. }   
  39. }   
  40. function Add() {   
  41. var request = db.transaction([“users”], “readwrite”)
      
  42. .objectStore(“users”)   
  43. .add({ id: “3”, name: “Gautam”, age: 30, email: “[email protected]” });
      
  44.     
  45. request.onsuccess = function(e) {   
  46. alert(“Gautam has been added to the database.”);   
  47. };   
  48.     
  49. request.onerror = function(e) {   
  50. alert(“Unable to add the information.”);    
  51. }   
  52.     
  53. }   
  54. function Read() {   
  55. var objectStore = db.transaction(“users”).objectStore(“users”);
      
  56. var request = objectStore.get(“2”);   
  57. request.onerror = function(event) {   
  58. alert(“Unable to retrieve data from database!”);   
  59. };   
  60. request.onsuccess = function(event) {    
  61. if(request.result) {   
  62. alert(“Name: ” + request.result.name + “, Age: ” + request.result.age + “, Email: ” + request.result.email);
      
  63. } else {   
  64. alert(“Bidulata couldn’t be found in your database!”);    
  65. }   
  66. };   
  67. }   
  68. function ReadAll() {   
  69. var objectStore = db.transaction(“users”).objectStore(“users”); 
      
  70. var req = objectStore.openCursor();   
  71. req.onsuccess = function(event) {   
  72. db.close();   
  73. var res = event.target.result;   
  74. if (res) {   
  75. alert(“Key ” + res.key + ” is ” + res.value.name + “, Age: ” + res.value.age + “, Email: ” + res.value.email);
      
  76. res.continue();   
  77. }   
  78. };   
  79. req.onerror = function (e) {   
  80. console.log(“Error Getting: “, e);   
  81. };    
  82. }   
  83. function Remove() {    
  84. var request = db.transaction([“users”], “readwrite”).objectStore(“users”).delete(“1”);
      
  85. request.onsuccess = function(event) {   
  86. alert(“Tapas’s entry has been removed from your database.”);   
  87. };   
  88. }   
  89. </script>  
  90. </head>  
  91.     
  92. <body>  
  93. <button onclick=”Add()”>Add record</button>  
  94. <button onclick=”Remove()”>Delete record</button>  
  95. <button onclick=”Read()”>Retrieve single record</button>  
  96. <button onclick=”ReadAll()”>Retrieve all records</button>  
  97. </body>  
  98. </html>  

localStorage是不带lock效用的。那么要促成前端的数码分享而且必要lock功用那就要求使用另外本积存情势,譬如indexedDB。indededDB使用的是事务管理的机制,那其实便是lock作用。
  做那个测量检验须求先简单的包装下indexedDB的操作,因为indexedDB的连日相比较费心,何况三个测验页面都亟待用到

JavaScript
Code复制内容到剪贴板

  1. //db.js   
  2. //封装事务操作   
  3. IDBDatabase.prototype.doTransaction=function(f){   
  4.   f(this.transaction([“Obj”],”readwrite”).objectStore(“Obj”));   
  5. };   
  6. //连接数据库,成功后调用main函数   
  7. (function(){   
  8.   //展开数据库   
  9.   var cn=indexedDB.open(“TestDB”,1);   
  10.   //成立数量对象   
  11.   cn.onupgradeneeded=function(e){   
  12.     e.target.result.createObjectStore(“Obj”);   
  13.   };   
  14.   //数据库连接成功   
  15.   cn.onsuccess=function(e){   
  16.     main(e.target.result);   
  17.   };   
  18. })();   
  19.   接着是三个测量试验页面   
  20. <script src=”db.js”></script>  
  21. <script>  
  22. //a.html   
  23. function main(e){   
  24.   (function callee(){   
  25.     //开始二个事务   
  26.     e.doTransaction(function(e){   
  27.       e.put(1,”test”); //设置test的值为1   
  28.       e.put(2,”test”); //设置test的值为2   
  29.     });   
  30.     setTimeout(callee);   
  31.   })();   
  32. };   
  33. </script>  
  34. <script src=”db.js”></script>  
  35. <script>  
  36. //b.html   
  37. function main(e){   
  38.   (function callee(){   
  39.     //开始贰个工作   
  40.     e.doTransaction(function(e){   
  41.       //获取test的值   
  42.       e.get(“test”).onsuccess=function(e){   
  43.         console.log(e.target.result);   
  44.       };   
  45.     });   
  46.     setTimeout(callee);   
  47.   })();   
  48. };   
  49. </script>  

把localStorage换到了indexedDB事务处理。可是结果就不一致

图片 2

测验的时候b.html中只怕不会及时有出口,因为indexedDB正忙着管理a.html东西,b.html事务丢在了作业丢队列中等待。可是无论怎么样,输出结果也不会是1那么些值。因为indexedDB的细微管理单位是业务,并非localStorage那样以表达式为单位。那样只要把lock和unlock之间须要管理的东西纳入几个事务中就可以兑现。别的,浏览器对indexedDB的接济不比localStorage,所以利用时还得思虑浏览器宽容。

那篇小说首要介绍了深深剖析HTML5中的IndexedDB索引数据库,包涵事务锁等基本功效的连锁使…

统一筹划指南

IndexedDB的架构很像在有些风靡的劳务器端NOSQL数据库达成中的设计指南类型。面向对象数据经过object
stores(对象货仓)实行持久化,全体操作基于央求同一时候在业务限制内实践。事件生命周期使您可见调整数据库的安顿,错误通过荒谬冒泡来使用API管理。

对象酒馆

object
store是IndexedDB数据库的根基。借使您使用过关全面据库,平日能够将object
store等价于二个多少库表。Object
stores包含二个或四个目录,在store中遵守一对键/值操作,那提供一种高效稳固数据的办法。

当您安顿几个object
store,你必得为store接纳贰个键。键在store中能够以“in-line”或“out-of-line”的法子存在。in-line键通过在数量对象上引用path来保持它在object
store的独一性。为了证实那或多或少,想想三个席卷电子邮件地址属性Person对象。您可以布置你的store使用in-line键emailAddress,它能保障store(长久化对象中的数据)的独一性。其余,out-of-line键通过独立于数据的值识别独一性。在这种场合下,你能够把out-of-line键比作三个整数值,它(整数值)在关周到据库中担纲记录的主键。

图1出示了职责数据保存在职分的object
store,它使用in-line键。在那个案例中,键对应于对象的ID值。

听大人说事务

差异于一些守旧的关全面据库的达成,每贰个对数据库操作是在叁个作业的内外文中实行的。事务限制贰遍影响一个或三个object
stores,你通过传播贰个object store名字的数组到开创职业限制的函数来定义。

开创专业的第二个参数是事情格局。当呼吁一个事务时,必须调节是依据只读照旧读写形式恳求访谈。事务是能源密集型的,所以如若您无需更换data
store中的数据,你只需求以只读格局对object stores群集举办呼吁访问。

清单2演示了哪些使用相当的形式创制二个事情,并在那片小说的 Implementing
Database-Specific Code
 部分开展了详尽座谈。

据说央浼

直至这里,有八个频仍出现的核心,您大概早就注意到。对数据库的历次操作,描述为经过三个伸手张开数据库,访谈三个object
store,再持续。IndexedDB
API天生是依照央求的,那也是API异步特性提醒。对于你在数据库实践的每趟操作,你必得首先为那些操作创设三个伏乞。当呼吁完结,你能够响应由乞请结果产生的平地风波和谬误。

本文完毕的代码,演示了什么利用央浼张开数据库,创制贰个工作,读取object
store的内容,写入object store,清空object store。

开垦数据库的乞请生命周期

IndexedDB使用事件生命周期管理数据库的张开和安顿操作。图2演示了三个开垦的央求在一定的意况下发生upgrade
need事件。

图片 3

图2:IndexedDB展开央浼的生命周期

富有与数据库的交互开头于贰个展开的伏乞。试图展开数据库时,您必需传递二个被呼吁数据库的本子号的整数值。在开辟请求时,浏览器相比较你传入的用来展开央求的版本号与事实上数据库的版本号。借使所须要的版本号高于浏览器中当前的版本号(恐怕以后并没有存在的数据库),upgrade
needed事件触发。在uprade
need事件时期,你有空子通过丰裕或移除stores,键和索引来操纵object stores。

如若所央浼的数据库版本号和浏览器的当下版本号同样,或然升级进度一呵而就,四个开发的数据库将回到给调用者。

荒唐冒泡

自然,不常候,必要或然不会按预想完毕。IndexedDB
API通过荒谬冒泡效果来提携追踪和治本破绽相当多。假使贰个特定的央浼蒙受错误,你能够品味在呼吁对象上管理错误,或然你能够允许错误通过调用栈冒泡向上传递。这几个冒泡个性,使得你无需为各类诉求完结特定错误管理操作,而是能够采取只在五个越来越高端别上增加错误管理,它给你多个机遇,保持你的错误管理代码简洁。本文中贯彻的例子,是在一个高端别管理错误,以便更加细粒度操作发生的别样不当冒泡到通用的错误管理逻辑。

浏览器援救

恐怕在支付Web应用程序最关键的标题是:“浏览器是或不是辅助笔者想要做的?“固然浏览器对IndexedDB的协助在后续增加,采纳率并不是大家所希望的那么普及。图3显得了caniuse.com网址的报告,帮忙IndexedDB的为66%多一丝丝。最新版本的银狐,Chrome,Opera,Safar,iOS
Safari,和Android完全支持IndexedDB,Internet
Explorer和华为部分帮忙。就算那几个列表的协助者是激动的,但它从未告诉全体遗闻。

图片 4

图3:浏览器对IndexedDB的帮助,来自caniuse.com

独有丰富新本子的Safari和iOS Safari
补助IndexedDB。据caniuse.com显示,那只占大概0.01%的全球浏览器选择。IndexedDB不是贰个您以为能够不移至理获得扶助的现世Web
API,不过你将相当的慢会那样感觉。

另一种选用

浏览器协理本地数据库实际不是从IndexedDB才开头达成,它是在WebSQL落到实处之后的一种新办法。类似IndexedDB,WebSQL是二个顾客端数据库,但它看成多个关全面据库的兑现,使用结构化查询语言(SQL)与数据库通信。WebSQL的历史充满了卷曲,但底线是从未主流的浏览器商家对WebSQL继续辅助。

只要WebSQL实际上是二个甩掉的手艺,为何还要提它吗?风趣的是,WebSQL在浏览器里猎取加强的帮忙。Chrome,
Safari, iOS Safari, and
Android 浏览器都援救。别的,并非那些浏览器的新型版本才提供协理,好些个这一个新颖最棒的浏览器在此以前的本子也足以支持。有意思的是,假诺你为WebSQL增多帮助来支撑IndexedDB,你卒然开掘,多数浏览器商家和版本成为支撑浏览器内置数据库的某种化身。

为此,假诺您的应用程序真正须要一个客户端数据库,你想要到达的最高档其他行使大概,当IndexedDB不可用时,只怕你的应用程序大概看起来须求采纳使用WebSQL来支撑客商端数据架构。即使文书档案数据库和关周全据库管理数占领醒指标差距,但假使您有不错的肤浅,就足以运用本地数据库塑造叁个应用程序。

发表评论

电子邮件地址不会被公开。 必填项已用*标注