About IndexDB

IndexedDB是用于客户端的大量的结构化数据存储和使用索引高效率搜索数据的API,它是基于W3C拟定的草案索引数据库的API。相对DOM存储的小存储数据量,IndexedDB具有大容量的数据存储功能,它分别为同步数据和异步数据提供的API,但目前只有异步数据的APIGecko2.0 上实现。

一、 概述

1. IndexedDB存储为键值对:它可以存储一些复杂的对象,而键可以存储这些对像的属性值,并且可以使用索引对对象的属性的快速检索。

2. IndexedDB建立在交互数据库模型的基础上:任何对IndexedDB的操作都发生一个交互操作(transaction),如它提供的索引、表、游标等均与一个transaction关联,它定义了交互的生存时间与结束时抛出的事件,这样能很好的处理web程序在不同的tab窗口中实例的互操作。

3. IndexedDBAPI大多是异步的:你可以向数据库发出操作的“请求”,当操作完成时会产生一个DOM事件,通过事件的类型会知道操作是否成功。

4. IndexedDB使用“请求”机制:操作对象会接收到DOMsuccessfailure事件,它也有相应的onsuccessonerror的属性;对象还有readyStateresulterrorCode属性来查看当前“请求”的状态,而result属性则根据不同的“请求”返回不同的结果。

5. IndexedDB 使用DOM事件机制来处理“请求”的结果:DOM事件的type属性提示操作是否成功,target属性指向发生“请求”的对象(大多数情况下是IDBRequest对象)。

6. IndexedDB工作基本模式:

创建一个交互操作对象

发送操作“请求”

通过监听DOM事件等待操作完成

处理“请求”结果

二、 打开数据库

IndexedDB的操作对象是以moz开头,如我们打开一个数据库如下:

 

1 var request = mozIndexedDB.open("MyTestDatabase");

mozIndexedDB对象只有一个open方法,它的参数即为数据库的名称,它返回一个IDBRequest对象。接下来要做的就是为request添加onsuccessonerror事件的处理,它们分别在返回的DOM事件的typesuccesserror时调用,

01 request.onerror = function(event) {
02  
03   // Do something with request.errorCode!
04  
05 };
06  
07 request.onsuccess = function(event) {
08  
09   // Do something with request.result!
10  
11 };

IndexedDB采用最小化的错误事件处理,你不会看到很多类型的错误,它只提供一个错误的事件,可以通过event.target.errorCode来查看错误的信息,通常大多的错误都是用户不允许web操作本地的数据库,远程web所拥有的权限问题。

三、 设置数据库的version

当创建数据库之后,需要添加数据,IndexedDB采用对象存储。首先要检查数据库的版本,若不是所期望的值,就要调用setVerion()方法来设置它的版本,如:

01 if (db.version != "1.0") {
02  
03   var request = db.setVersion("1.0");
04  
05   request.onerror = function(event) {
06  
07     // Handle errors.
08  
09   };
10  
11   request.onsuccess = function(event) {
12  
13     // Set up the database structure here!
14  
15   };
16  
17 }

IndexedDB存储的每一个对象均与一个key 关联,关于key 的获取方法参见()。同时我们还可以为对你的存储创建一个Index来查看存储对象部分属性值,如存储人的信息的数据库,我们希望保证不同的人拥有不同的email,就可以使用indexunique flag来设置,如:

01 // This is what our customer data looks like.
02  
03 const customerData = [
04  
05   { ssn: "444-44-4444", name: "Bill", age: 35, email: "[email protected]" },
06  
07   { ssn: "555-55-5555", name: "Donna", age: 32, email: "[email protected]" }
08  
09 ];
10  
11 var request = db.setVersion("1.0");
12  
13 request.onerror = function(event) {
14  
15   // Handle errors.
16  
17 };
18  
19 request.onsuccess = function(event) {
20  
21   // Create an objectStore to hold information about our customers. We're
22  
23   // going to use "ssn" as our key path because it's guaranteed to be
24  
25   // unique.
26  
27   var objectStore = db.createObjectStore("customers", { keyPath: "ssn" });
28  
29   // Create an index to search customers by name. We may have duplicates
30  
31   // so we can't use a unique index.
32  
33   objectStore.createIndex("name""name", { unique: false });
34  
35   // Create an index to search customers by email. We want to ensure that
36  
37   // no two customers have the same email, so use a unique index.
38  
39   objectStore.createIndex("email""email", { unique: true });
40  
41   // Store values in the newly created objectStore.
42  
43   for (i in customerData) {
44  
45     objectStore.add(customerData[i]);
46  
47   }
48  
49 };

  creatObjectStore()方法和createIndex()方法都有一个可选的对象选项来区分是创建数据库还是索引。creatObjectStore()方法会请求“customers创建存储对象,并以ssn属性为存储对象的键值,任何试图存储进数据库的对象都需要有ssn属性;我们也可以通name的这个Index来查看存储对象,但对于没有name属性的对象将不会显示出来。

向数据库中添加数据

四、 在添加数据之前,需要先创建一个transaction,创建的方法有三个参数,后两个为可选的,第一个为要关联的数据库名称数组,第二个为打开此数据库的方式(如只读),若无则打开的方式为只读,如:

var transaction = db.transaction(["customers"],IDBTransaction.READ_WRITE);

一个transaction生存时间是与DOM 事件相关联的,如果创建它之后并在返回的事件中没有使用它,就会消亡,唯一让它处理激活状态的就去是使用“请求”机制,当一个请求完成后,在它的回调函数中继续请求,否则transaction就是会消亡。一个transaction有三个事件,为onerroronsuccessonabort,一个简单的例子:

01 // Do something when all the data is added to the database.
02  
03 transaction.oncomplete = function(event) {
04  
05   alert("All done!");
06  
07 };
08  
09 transaction.onerror = function(event) {
10  
11   // Don't forget to handle errors!
12  
13 };
14  
15 var objectStore = transaction.objectStore("customers");
16  
17 for (var in customerData) {
18  
19   var request = objectStore.add(customerData[i]);
20  
21   request.onsuccess = function(event) {
22  
23     // event.target.result == customerData[i].ssn
24  
25   };
26  
27 }

五、 从数据库中删除数据

删除数据很简单,如下:

01 var request = db.transaction(["customers"], IDBTransaction.READ_WRITE)
02  
03                 .objectStore("customers")
04  
05                 .delete("444-44-4444");
06  
07 request.onsuccess = function(event) {
08  
09   // It's gone!
10  
11 };

六、 数据库中取数据

使用get()方法,参数为存储对象的key,如:

1 db.transaction("customers").objectStore("customers").get("444-44-4444").onsuccess = function(event) {
2  
3   alert("Name for SSN 444-44-4444 is " + event.target.result.name);
4  
5 };

七、 使用游标

使用get()方法需要知道存储对象的key值,但若不知道key值,要看存储对象,就可以使用游标,如下:

01 var objectStore = db.transaction("customers").objectStore("customers");
02  
03 objectStore.openCursor().onsuccess = function(event) {
04  
05   var cursor = event.target.result;
06  
07   if (cursor) {
08  
09     alert("Name for SSN " + cursor.key + " is " + cursor.value.name);
10  
11     cursor.continue();
12  
13   }
14  
15   else {
16  
17     alert("No more entries!");
18  
19   }
20  
21 };

openCursor()方法有许多参数,首先你可设置遍历的Key的范围,其次可以设置游标遍历的方向。Continue();表示继续遍历。

八、 使用索引

在数据库中,所有的数据都是以SSNkey值来存储的,若要通过name等其他属性查看存储对象,需要遍历每个SSN并将它的name提取出判断是否为要查看的对象,但可以通过index而更为简单的实现,如:

1 var index = objectStore.index("name");
2  
3 index.get("Donna").onsuccess = function(event) {
4  
5   alert("Donna's SSN is " + event.target.result.ssn);
6  
7 };

我们还可以通过index使用cursor来遍历存储的数据,并根据不同的cursor打开方式,返回不同的遍历结果,如下两种方式:

01 index.openCursor().onsuccess = function(event) {
02  
03   var cursor = event.target.result;
04  
05   if (cursor) {
06  
07     // cursor.key is a name, like "Bill", and cursor.value is the whole object.
08  
09     alert("Name: " + cursor.key + ", SSN: " + cursor.value.ssn + ", email: "+ cursor.value.email);
10  
11     cursor.continue();
12  
13   }
14  
15 };
16  
17 index.openKeyCursor().onsuccess = function(event) {
18  
19   var cursor = event.target.result;
20  
21   if (cursor) {
22  
23     // cursor.key is a name, like "Bill", and cursor.value is the SSN.
24  
25     // No way to directly get the rest of the stored object.
26  
27     alert("Name: " + cursor.key + ", "SSN: " + cursor.value);
28  
29     cursor.continue();
30  
31   }
32  
33 };

九、 关于游标遍历的范围和方向

如果想要限制游标的遍历范围,可以使用“key range”的对象,并将它做为openCursor()openKeyCursor()的第一个参数,这样的范围可以是单个键值、或是一个最低边界和最高边界的范围,并规定是否包括范围,如下:

01 // Only match "Donna"
02  
03 var singleKeyRange = IDBKeyRange.only("Donna");
04  
05 // Match anything past "Bill", including "Bill"
06  
07 var lowerBoundKeyRange = IDBKeyRange.lowerBound("Bill");
08  
09 // Match anything past "Bill", but don't include "Bill"
10  
11 var lowerBoundOpenKeyRange = IDBKeyRange.lowerBound("Bill"true);
12  
13 // Match anything up to, but not including, "Donna"
14  
15 var upperBoundOpenKeyRange = IDBKeyRange.upperBound("Donna"true);
16  
17 //Match anything between "Bill" and "Donna", but not including "Donna"
18  
19 var boundKeyRange = IDBKeyRange.bound("Bill""Donna"falsetrue);
20  
21 index.openCursor(boundKeyRange).onsuccess = function(event) {
22  
23   var cursor = event.target.result;
24  
25   if (cursor) {
26  
27     // Do something with the matches.
28  
29     cursor.continue();
30  
31   }
32  
33 };

另外,还可以规定游标遍历的方向,默认的是上升的方向,若使用相反的方向,可以将PREV作为openCursor()或是openKeyCursor()的第二个参数,如下:

01 objectStore.openCursor(null

你可能感兴趣的:(数据库,function,database,存储,email,generator)