HTML5存储之 indexedDB

 IndexeDB是HTML5 重要的一部分,它是一种轻量级的NOSQL数据库.对创建具有丰富本地存储数据的数据密集型的离线HTML5 Web 应用程序很有用. 

IndexedDB是为了能够在客户端存储大量的结构化数据,并且使用索引高效检索的API。同时还有助于本地缓存数据,是Web应用程序可以更快的运行和相应,提高用户的体验度.

那么说了这么多,IndexedDB这个到底是个什么东东呢 ? 我个人理解IndexedDB 就是一种能在浏览器中持久地存储结构化数据的数据库,并且为WEB应用提供了丰富的查询能力.

如果你想要了解更多,请点击https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Concepts_Behind_IndexedDB

概念:

一个网站可能有一个或多个 IndexedDB 数据库,每个数据库必须具有惟一的名称。

一个数据库可包含一个或多个对象存储。一个对象存储(由一个名称惟一标识)是一个记录集合。每个记录有一个键 和一个值。该值是一个对象,可拥有一个或多个属性。键可能基于某个键生成器,从一个键路径衍生出来,或者是显式设置。一个键生成器自动生成惟一的连续正整数。键路径定义了键值的路径。它可以是单个 JavaScript 标识符或多个由句点分隔的标识符。

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

规范中包含一个异步 API 和一个同步 API。同步 API 用于 Web 浏览器中。异步 API 使用请求和回调。

IndexedDB遵循同源策略。因此,尽管您可以访问存储的数据在一个领域,你不能访问数据在不同的领域。

好了说了这么多,下面我们 就来真正了解它吧!

 我们在打开IndexedDB之前,我们要先判断一下它是否支持的现在的浏览器.

window.indexedDB=window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB;

if(window.indexedDB){
alert("您的浏览器支持IndexedDB数据库。");
} else{
alert("您的浏览器不支持IndexedDB数据库。");
}

判断完成之后我们就可以开始进行下面的操作.

indexedDB 打开数据库的方法只有一种.就是 open 用于打开指定的数据库.

语法:request对象 = window.indexedDB.open(数据库名, 数据库版本号)

var dbName = "mysql";

var request = window.indexedDB.open(dbName,1.0); // 数据库版本可写可不写,默认0

在控制台打印 

处理错误或异常和调试

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

所有异步请求都有一个 onsuccess 回调和一个 onerror 回调,前者在数据库操作成功时调用,后者在一个操作未成功时调用。

request对象用于处理用户对数据库的操作请求。可以通过它定义操作成功和失败的处理函数。

repuest.onsuccess = function(event) {}; //异步成功处理函数

request.onerror = function(event){}; // 异步失败处理函数

IndexedDB 很难调试和排除故障,因为在许多情况下,错误消息是泛泛的,缺乏信息价值。在开发应用程序时,可以使用 console.log 调试。

IDBOpenDBRequest接口定一个几个重要的属性:

1.onerror: 请求失败的回调函数句柄

2.onsuccess:请求成功的回调函数句柄

3.onupgradeneeded:请求数据库版本变化句柄

1和2 上面已经说过了 ,onupgradeneeded 请求是在数据库第一次被打开时;打开数据库时指定的版本号高于当前被持久化的数据库.的时候触发。

使用数据库

1. 创建 一个数据库  (包括创建对象存储空间)

function createDatabase(){
var request = var request = window.indexedDB.open(dbName);
request.onerror = function(){};
request.onsuccess = function(){};
request.onupqradeneeded = function(){
mydb=request.result;//获得数据库实例对象
//判断对象存储空间名称是否已经存在
if(!mydb.objectStoreNames.contains("students")) {
//创建students对象存储空间;指定keyPath选项为id(即主键为id)
var objectStore = mydb.createObjectStore("students", {keyPath: "id"});
//对象存储空间students的列email上创建一个唯一索引email,可以创建多个索引。
// objectStore.createIndex("name","name",{unique:false}); 也可以这样 创建两个索引
// objectStore.createIndex("phone","phone",{unique:false});
objectStore.createIndex("email", //索引名
             "email",//创建索引的列(即keyPath,索引属性字段名)
             { unique: true });//索引选项(索引属性值是否唯一:true or false)
}
};
}

在增 ,删,改,查 中都要用到事务的方法

//-------------查询数据----------

function get(mydb){
var transaction = mydb.transaction('students','readwrite');
transaction.oncomplete = function(event) {};
transaction.onerror = function(event) {};
transaction.onabort = function(event){};
var objStore = transaction.objectStore('students');
var request = objStore.get("110"); //按照id查询
request.onsuccess=function(e){
alert(e.target.result.name + e.target.result.age + e.target.result.email);
}
}

//----------更新数据-------------

function update(mydb){
var transaction = mydb.transaction('students','readwrite');
transaction.oncomplete = function(event) {};
transaction.onerror = function(event) {};
transaction.onabort = function(event){};
var objStore = transaction.objectStore('students');
var request = objStore.get("110");
request.onsuccess=function(e){
var student=e.target.result;

student.name='wwww1';
objStore.put(student);
}

//-------------删除 数据--------------

function remove(mydb){
var transaction = mydb.transaction('students','readwrite');
transaction.oncomplete = function(event) {};
transaction.onerror = function(event) {};
transaction.onabort = function(event){};
var objStore = transaction.objectStore('students');
var request = objStore.delete("110"); // 为我们提供的方法
request.onsuccess = function(e) {
alert("成功删除数据");
};
}
}

//-------利用索引查询-------

function byIndexGet(mydb){
var transaction = mydb.transaction('students','readwrite');
transaction.oncomplete = function(event) {};
transaction.onerror = function(event) {};
transaction.onabort = function(event){};
var objStore = transaction.objectStore('students');
var index = objStore.index('email'); //索引名
var request=index.get('liming1@email.com'); //通过索引值获取数据
request.onsuccess=function(e){
var student=e.target.result;

alert(student.name+":索引查询");

}
}

//---------------游标遍历----------

//这是indexDB 里面重要的部分 IndexedDB 中的游标是双向的,这提供了额外的灵活性。
//语法:var request=objStore.openCursor() // 打开游标
function byCursorGet(mydb){
var transaction = mydb.transaction('students','readwrite');
transaction.oncomplete = function(event) {};
transaction.onerror = function(event) {};
transaction.onabort = function(event){};
var objStore = transaction.objectStore('students');
var request=objStore.openCursor();//打开游标
request.onsuccess = function(e){
var cursor = e.target.result;
if(cursor){
alert(cursor.value.name);
cursor.continue();
}else {
alert('遍历完成');
}
}
}


//----------通过范围和排序条件,游标遍历符合条件的
下面是 一些参数的值
/**
* 范围:
*(1)匹配等于指定键值的记录:var range = IDBKeyRange.only(指定键值)
*(2)匹配小于指定键值的记录:var range = IDBKeyRange.lowerBound(指定键值, 是否不包括指定键值)
*(3)匹配大于指定键值的记录:var range = IDBKeyRange.upperBound(指定键值, 是否不包括指定键值)
*(4)匹配指定范围内的记录:var range = IDBKeyRange.bound(下限键值,上限键值,是否不包括下限键值,是否不包括上限键值
*/ 例如: // 只取得当前索引的值为110的数据 IDBKeyRange.only("110");
// 只取得当前索引的值大于110,并且不包括110的数据
------IDBKeyRange.lowerBound("110", true);
// 只取得当前索引的值小于110,并且包括110的数据
------IDBKeyRange.upperBound("110", false);
// 取得当前索引的值介于110和120之间,并且包括110,但不包括120的数据
-----IDBKeyRange.bound("110", "120", false, true);
/**
* 顺序参数:
* IDBCursor.NEXT,顺序循环; -- 默认
* IDBCursor.NEXT_NO_DUPLICATE,顺序循环且键值不重复;
* IDBCursor.PREV,倒序循环;
* IDBCursor.PREV _NO_DUPLICATE,倒序循环且键值不重复。
*/

下面是具体的代码:

function byCursorGetForRangeAndSort(mydb){
var transaction = mydb.transaction('students','readwrite');
transaction.oncomplete = function(event) {};
transaction.onerror = function(event) {};
transaction.onabort = function(event){};
var objStore = transaction.objectStore('students');
var range = IDBKeyRange.bound("110", "113", false, true); //范围
var request=objStore.openCursor(range, //范围(可以为null或省略不写) IDBCursor.NEXT); //游标顺序循环(可以省略不写)
request.onsuccess = function(e){
var cursor1 = e.target.result;
if(cursor1){
alert(cursor1.value.name);
cursor1.continue();
}else {
alert('遍历完成');
}
}
}


//----------------清除数据库-------
window.indexedDB.deleteDatabase(dbName);
//--------------关闭连接
mydb.close(); //关闭连接

最后

   IndexedDB API 非常强大,您可以使用它创建具有丰富本地存储数据的数据密集型应用程序(尤其是离线的 HTML5 Web 应用程序)。您还可以使用 IndexedDB API 将数据缓存到本地,使传统的在线 Web 应用程序(尤其是移动 Web 应用程序)能够更快地运行和响应,从而消除每次从 Web 服务器检索数据的需求。例如,可以将选择列表的数据缓存在 IndexedDB 数据库中。

  本文展示了如何管理 IndexedDB 数据库,包括创建数据库,删除数据库,以及建立与数据库的连接。本文还展示了 IndexedDB API 的许多更高级的功能,包括事务处理、索引和游标。您可以使用这些展示的概念构建利用 IndexedDB API 的离线应用或移动 Web 应用程序。  

   如果有什么问题或者不对的地方,大家可以留言。

原文地址:https://www.cnblogs.com/Sabo-dudu/p/6030799.html