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

前者的数据库:IndexedDB入门

2014/12/27 · 未分类 · IndexedDB

本文由 伯乐在线 –
cucr
翻译,黄利民
校稿。未经许可,禁绝转发!
拉脱维亚语出处:www.codemag.com。应接参预翻译组。

应用程序要求多少。对比很多Web应用程序来讲,数据在劳务器端组织和处理,顾客端通过互联网央浼获取。随着浏览器变得极其有工夫,由此可选用在浏览器存款和储蓄和垄断(monopoly)应用程序数据。

本文向您介绍名称为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请参照他事他说加以考察完整文书档案

深深分析HTML第55中学的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”的对象存款和储蓄,并定义了key帕特h,那是目的独一性的性质。
    在这里,大家采纳“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个参数(第三个和第多少个是可选的)。
第三个是咱们要管理的目的存款和储蓄的列表,第二个内定我们是还是不是要只读/读写,第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来协助客商端数据架构。即使文档数据库和关周到据库管理数占有令人瞩目标反差,但只要你有不利的肤浅,就足以采纳本地数据库构建二个应用程序。

发表评论

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