HTML5 -- 浏览器数据缓存 -- indexedDB【上海时时乐走

  var updataVersion = function (db, storeName, version) {
    closeIDB(db)
    console.log('更新版本', storeName, version)
    openIDB(storeName, version)
  }

深入解析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事务处理。但是结果就不同

上海时时乐走势图官网 1

测试的时候b.html中可能不会立即有输出,因为indexedDB正忙着处理a.html东西,b.html事务丢在了事务丢队列中等待。但是无论如何,输出结果也不会是1这个值。因为indexedDB的最小处理单位是事务,而不是localStorage那样以表达式为单位。这样只要把lock和unlock之间需要处理的东西放入一个事务中即可实现。另外,浏览器对indexedDB的支持不如localStorage,所以使用时还得考虑浏览器兼容。

这篇文章主要介绍了深入解析HTML5中的IndexedDB索引数据库,包括事务锁等基本功能的相关使...

更新数据

可以调用object store的put方法更新数据,会自动替换键值相同的记录,达到更新目的,没有相同的则添加,以使用keyPath做键为例

function updateDataByKey(db,storeName,value){              var transaction=db.transaction(storeName,'readwrite');               var store=transaction.objectStore(storeName);               var request=store.get(value);               request.onsuccess=function(e){                   var student=e.target.result;                   student.age=35;                  store.put(student);               };  }
  // 清空store
  var clearObjectStore = function (db, storeName) {
    let transaction = db.transaction(storeName, 'readwrite')
    let store = transaction.objectStore(storeName)
    let request = store.clear()
    request.onsuccess = function () {
      console.log('清空成功')
    }
    request.onerror = function () {
      console.log('清空失败')
    }
  }

事务

在对新数据库做任何事情之前,需要开始一个事务。事务中需要指定该事务跨越哪些object store。

事务具有三种模式

  1. 只读:read,不能修改数据库数据,可以并发执行
  2. 读写:readwrite,可以进行读写操作
  3. 版本变更:verionchange

 

var transaction=db.transaction([students','taecher']);  //打开一个事务,使用students 和teacher object store  var objectStore=transaction.objectStore('students'); //获取students object store

由于 IndexedDB 本身的规范还在持续演进中,当前的 IndexedDB 的实现还是使用浏览器前缀。在规范更加稳定之前,浏览器厂商对于标准 IndexedDB API 可能都会有不同的实现。但是一旦大家对规范达成共识的话,厂商就会不带前缀标记地进行实现。实际上一些实现已经移除了浏览器前缀:IE 10,Firefox 16 和 Chrome 24。

在HTML5本地存储——Web SQL Database提到过Web SQL Database实际上已经被废弃,而HTML5的支持的本地存储实际上变成了

// 打开我们的数据库,版本号为1
var request = window.indexedDB.open("MyTestDatabase", 1);

object store

有了数据库后我们自然希望创建一个表用来存储数据,但indexedDB中没有表的概念,而是objectStore,一个数据库中可以包含多个objectStore,objectStore是一个灵活的数据结构,可以存放多种类型数据。也就是说一个objectStore相当于一张表,里面存储的每条数据和一个键相关联。

我们可以使用每条记录中的某个指定字段作为键值(keyPath),也可以使用自动生成的递增数字作为键值(keyGenerator),也可以不指定。选择键的类型不同,objectStore可以存储的数据结构也有差异

键类型 存储数据
不使用 任意值,但是没添加一条数据的时候需要指定键参数
keyPath Javascript对象,对象必须有一属性作为键值
keyGenerator 任意值
都使用 Javascript对象,如果对象中有keyPath指定的属性则不生成新的键值,如果没有自动生成递增键值,填充keyPath指定属性

 

var students: [
        { id: 1001, name: "Byron", age: 24 }, 
        { id: 1002, name: "Frank", age: 30 }, 
        { id: 1003, name: "Aaron", age: 26 }, 
        { id: 1004, name: "Casper", age: 26 }
]
// 添加数据方法 在onsuccess中执行
var addData = function (db, storeName) {
    console.log('addData success')
    let transaction = db.transaction(storeName, 'readwrite')
    let store = transaction.objectStore(storeName)
    let request = null

    for (let i = 0; i < students.length; i  ) {
      request = store.add(tstudents[i])
      request.onerror = function () {
        console.error('数据库已有该数据!')
      } 
      request.onsuccess = function () {
        console.log('添加成功')
      }
    }
}

异步API

在IndexedDB大部分操作并不是我们常用的调用方法,返回结果的模式,而是请求——响应的模式,比如打开数据库的操作

var request=window.indexedDB.open('testDB');

这条指令并不会返回一个DB对象的句柄,我们得到的是一个IDBOpenDBRequest对象,而我们希望得到的DB对象在其result属性中,

上海时时乐走势图官网 2

这条指令请求的响应是一个 IDBDatabase对象,这就是IndexedDB对象,

上海时时乐走势图官网 3

 

除了result,IDBOpenDBRequest接口定义了几个重要属性

  • onerror: 请求失败的回调函数句柄
  • onsuccess:请求成功的回调函数句柄
  • onupgradeneeded:请求数据库版本变化句柄

 

所谓异步API是指并不是这条指令执行完毕,我们就可以使用request.result来获取indexedDB对象了,就像使用ajax一样,语句执行完并不代表已经获取到了对象,所以我们一般在其回调函数中处理。

删除表:

最后

 

这就是关于indexedDB的基本使用方式,很多同学看了会觉得很鸡肋,和我们正常自己定义个对象使用没什么区别,也就是能保存在本地罢了,这是因为我们还没有介绍indexedDB之所以称为indexed的杀器——索引,这个才是让indexedDB大显神通的东西,下篇我们就来看看这个杀器。


下面是整个数据库的操作流程:

version

我们注意到除了onerror和onsuccess,IDBOpenDBRequest还有一个类似回调函数句柄——onupgradeneeded。这个句柄在我们请求打开的数据库的版本号和已经存在的数据库版本号不一致的时候调用。

indexedDB.open()方法还有第二个可选参数,数据库版本号,数据库创建的时候默认版本号为1,当我们传入的版本号和数据库当前版本号不一致的时候onupgradeneeded就会被调用,当然我们不能试图打开比当前数据库版本低的version,否则调用的就是onerror了,修改一下刚才例子

function openDB (name,version) {              var version=version || 1;              var request=window.indexedDB.open(name,version);              request.onerror=function(e){                  console.log(e.currentTarget.error.message);              };              request.onsuccess=function(e){                  myDB.db=e.target.result;              };              request.onupgradeneeded=function(e){                  console.log('DB version changed to ' version);              };          }            var myDB={              name:'test',              version:3,              db:null          };          openDB(myDB.name,myDB.version);

由于刚才已经创建了版本为1的数据库,打开版本为3的时候,会在控制台输出:DB version changed to 3

删除数据库:

删除数据及object store

 

调用object store的delete方法根据键值删除记录

function deleteDataByKey(db,storeName,value){              var transaction=db.transaction(storeName,'readwrite');               var store=transaction.objectStore(storeName);               store.delete(value);           }

调用object store的clear方法可以清空object store

function clearObjectStore(db,storeName){              var transaction=db.transaction(storeName,'readwrite');               var store=transaction.objectStore(storeName);               store.clear();  }

调用数据库实例的deleteObjectStore方法可以删除一个object store,这个就得在onupgradeneeded里面调用了

if(db.objectStoreNames.contains('students')){                       db.deleteObjectStore('students');   }
  // 新增Store--带索引(在onupgradeneeded里调用)
  var createObjectStoreWidthIndex = function (db, storeName) {
    if (!db.objectStoreNames.contains(storeName)) {
      let store = db.createObjectStore(storeName, {
        keyPath: 'id'
      })
      store.createIndex('nameIndex', 'name', {
        unique: true
      })
      store.createIndex('ageIndex', 'age', {
        unique: false
      })
      console.log("createObjectStore:"   storeName   ",成功!")
    }
  }

给object store添加数据

 

调用数据库实例的createObjectStore方法可以创建object store,方法有两个参数:store name和键类型。调用store的add方法添加数据。有了上面知识,我们可以向object store内添加数据了

 

keyPath

因为对新数据的操作都需要在transaction中进行,而transaction又要求指定object store,所以我们只能在创建数据库的时候初始化object store以供后面使用,这正是onupgradeneeded的一个重要作用,修改一下之前代码

function openDB (name,version) {              var version=version || 1;              var request=window.indexedDB.open(name,version);              request.onerror=function(e){                  console.log(e.currentTarget.error.message);              };              request.onsuccess=function(e){                  myDB.db=e.target.result;              };              request.onupgradeneeded=function(e){                  var db=e.target.result;                  if(!db.objectStoreNames.contains('students')){                      db.createObjectStore('students',{keyPath:"id"});                  }                  console.log('DB version changed to ' version);              };          }

 

这样在创建数据库的时候我们就为其添加了一个名为students的object store,准备一些数据以供添加

var students=[{               id:1001,               name:"Byron",               age:24           },{               id:1002,               name:"Frank",               age:30           },{               id:1003,               name:"Aaron",               age:26           }];

function addData(db,storeName){              var transaction=db.transaction(storeName,'readwrite');               var store=transaction.objectStore(storeName);                 for(var i=0;i<students.length;i  ){                  store.add(students[i]);              }          }      openDB(myDB.name,myDB.version);          setTimeout(function(){              addData(myDB.db,'students');          },1000);

这样我们就在students object store里添加了三条记录,以id为键,在chrome控制台看看效果

上海时时乐走势图官网 4

 

keyGenerate

 

function openDB (name,version) {              var version=version || 1;              var request=window.indexedDB.open(name,version);              request.onerror=function(e){                  console.log(e.currentTarget.error.message);              };              request.onsuccess=function(e){                  myDB.db=e.target.result;              };              request.onupgradeneeded=function(e){                  var db=e.target.result;                  if(!db.objectStoreNames.contains('students')){                      db.createObjectStore('students',{autoIncrement: true});                  }                  console.log('DB version changed to ' version);              };          }

上海时时乐走势图官网 5

剩下的两种方式有兴趣同学可以自己摸索一下了

打开数据库:

查找数据

可以调用object store的get方法通过键获取数据,以使用keyPath做键为例

function getDataByKey(db,storeName,value){              var transaction=db.transaction(storeName,'readwrite');               var store=transaction.objectStore(storeName);               var request=store.get(value);               request.onsuccess=function(e){                   var student=e.target.result;                   console.log(student.name);               };  }
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange

Web Storage(Local Storage和Session Storage)与IndexedDB。Web Storage使用简单字符串键值对在本地存储数据,方便灵活,但是对于大量结构化数据存储力不从心,IndexedDB是为了能够在客户端存储大量的结构化数据,并且使用索引高效检索的API。

注意,在执行addData方法的时候,要确保已执行createObjectStore方法,否则会报错。添加完之后浏览器显示:

创建数据库

刚才的语句已经展示了如何打开一个indexedDB数据库,调用indexedDB.open方法就可以创建或者打开一个indexedDB。看一个完整的处理

function openDB (name) {              var request=window.indexedDB.open(name);              request.onerror=function(e){                  console.log('OPen Error!');              };              request.onsuccess=function(e){                  myDB.db=e.target.result;              };          }            var myDB={              name:'test',              version:1,              db:null          };          openDB(myDB.name);

代码中定义了一个myDB对象,在创建indexedDB request的成功毁掉函数中,把request获取的DB对象赋值给了myDB的db属性,这样就可以使用myDB.db来访问创建的indexedDB了。

  // 删除database
  var deleteIDB = function (db) {
    console.log('删除')
    window.indexedDB.deleteDatabase(db)
  }

关闭与删除数据库

关闭数据库可以直接调用数据库对象的close方法

function closeDB(db){              db.close();          }

删除数据库使用indexedDB对象的deleteDatabase方法

function deleteDB(name){              indexedDB.deleteDatabase(name);          }

简单调用

var myDB={              name:'test',              version:3,              db:null          };          openDB(myDB.name,myDB.version);          setTimeout(function(){              closeDB(myDB.db);              deleteDB(myDB.name);          },500);

由于异步API愿意,不能保证能够在closeDB方法调用前获取db对象(实际上获取db对象也比执行一条语句慢得多),所以用了setTimeout延迟了一下。当然我们注意到每个indexedDB实例都有onclose回调函数句柄,用以数据库关闭的时候处理,有兴趣同学可以试试,原理很简单,不演示了。

 

 

var db;
request.onerror = function(event) {
  // Do something with request.errorCode!
};
request.onsuccess = function(event) {
  db = event.target.result;
  // Do something with request.result!
};
  // 获取数据(根据索引)
  var getDataByIndex = function (db, storeName) {
    let transaction = db.transaction(storeName, 'readonly')
    let store = transaction.objectStore(storeName)
    let index = store.index('nameIndex')
    index.get('Byron').onsuccess = function (e) {
      let student = e.target.result
      console.log(student)
    }
  }
  // 使用游标
  var fetchStoreByCursor = function (db, storeName) {
    let transaction = db.transaction(storeName)
    let store = transaction.objectStore(storeName)
    let request = store.openCursor() // 查询全部
    request.onsuccess = function (e) {
      let cursor = e.target.result
      if (cursor) {
        let student = cursor.value
        console.log(student)
        cursor.continue()
      }
    }
  }
  // 索引与游标结合
  var getDataByMultiple = function (db, storeName) {
    // 指定游标范围
    // IDBKeyRange.only(value):只获取指定数据
    // IDBKeyRange.lowerBound(value,isOpen):获取比value大的数据(isOpen: true不包含value, false包含value)
    // IDBKeyRange.upperBound(value,isOpen):获取比value小的数据(isOpen: true不包含value, false包含value)
    // IDBKeyRange.bound(value1,value2,isOpen1,isOpen2)
    let transaction = db.transaction(storeName)
    let store = transaction.objectStore(storeName)
    let index = store.index('ageIndex')
    index.openCursor(IDBKeyRange.bound(24, 30, true, true)).onsuccess = function (e) {
      let cursor = e.target.result
      if (cursor) {
        let s = cursor.value
        console.log(s)
        cursor.continue()
      }
    }
  }
// 只有在onupgradeneeded方法中有效
var createObjectStore = function (db, storeName) {
    if (!db.objectStoreNames.contains(storeName)) {
      db.createObjectStore(storeName, {
        keyPath: 'id',
        autoIncrement: true
      })
      console.log("createObjectStore:"   storeName   ",成功!")
    }
}

IndexedDB是一种可以让你在用户的浏览器内持久化存储数据的方法,为web应用提供了丰富的查询功能,使我们的应用在在线和离线都能正常工作。

  // 更新数据
  var updateDataByKey = function (db, storeName, keyValue) {
    let transaction = db.transaction(storeName, 'readwrite')
    let store = transaction.objectStore(storeName)
    let request = store.get(keyValue)
    request.onsuccess = function (e) {
      let student = e.target.result
      student.age = 35
      store.put(student)
      console.log(student)
    }
  }

删除数据:

  // 查询数据(根据关键词keyValue)
  var getDataByKey = function (db, storeName, keyValue) {
    let transaction = db.transaction(storeName, 'readonly')
    let store = transaction.objectStore(storeName)

    let request = store.get(keyValue)
    request.onsuccess = function (e) {
      let result = e.target.result
      console.log(result)
    }
  }
  // 关闭database
  var closeIDB = function (db) {
    db.close()
    console.log('关闭')
  }

表中添加数据:

当我们创建一个新的数据表时,我们首先要在onupgradeneeded方法中创建表:

request还有一个回掉方法:

如果你希望在仍旧使用前缀的浏览器中测试你的代码, 可以使用下列代码:

查询数据:

关闭数据库:

上海时时乐走势图官网 6

几乎所有我们产生的请求我们在处理的时候首先要做的就是添加成功和失败处理函数:

新增表(带索引):

indexedDB打开数据库的方法如上,必须进行request,indexedDB只有一个open方法,上面的代码表示打开了一个"MyTestDatabase"的数据库,该方法可以接受第二个参数:

request.onupgradeneeded = function(event) {
  var _db = event.target.result;
  // Do something with request.result!
};

 

成功之后浏览器端显示:

onupgradeneeded方法是只有在版本号升级的情况下才会执行(如果当前版本号为1,当我们在打开open(storeName, 2)时,onupgradeneeded就会执行)。

// 打开我们的数据库
var request = window.indexedDB.open("MyTestDatabase");

要注意的是使用前缀的实现可能会有问题,或者是实现的并不完整,也可能遵循的还是旧版的规范。因此不建议在生产环境中使用。我们更倾向于明确的不支持某一浏览器,而不是声称支持但是实际运行中却出问题:

清空表:

 更新数据:

如果我们需要手动更新版本,我们先要将indexedDB关闭,然后再打开新版本的数据库:

// 删除Store(在onupgradeneeded里调用)
deleteObjectStore (db, storeName) {
    console.log('deleteObjectStore')
    if (db.objectStoreNames.contains(storeName)) {
      db.deleteObjectStore(storeName)
      console.log("deleteObjectStore:"   storeName   ",成功!")
    }
}
function hasIndexedDB () {
   if (!window.indexedDB) {
      return true;
   }
}

上海时时乐走势图官网 7

第二个参数的版本号为整数,当前打开的版本号不能比现有的版本号小,否则会报错。

  // 删除数据
  var deleteDataByKey = function (db, storeName, keyValue) {
    let transaction = db.transaction(storeName, 'readwrite')
    let store = transaction.objectStore(storeName)
    let result = store.delete(keyValue)
    result.onsuccess = function () {
      console.log('删除成功')
    }
    result.onerror = function () {
      console.log('删除失败')
    }
  }

获取数据的方法:

本文由上海时时乐走势图发布于web前端,转载请注明出处:HTML5 -- 浏览器数据缓存 -- indexedDB【上海时时乐走

您可能还会对下面的文章感兴趣: