之前的文章(http://www.cnblogs.com/wzh2010/archive/2012/05/22/2514017.html)里面描述了HTML5 离线数据存储的Web SQL,一个基于SQLite 的离线数据库,不过W3C 的 WebDatabase 规范中说这份规范不再维护了,取而代之的是IndexDB,一个NoSQL类型的数据库。

Html5Rocks把他们的优缺点做了比对,IndexDB综合看来有如下优点:
允许快速索引和搜索的对象,所以在HTML5 的 web应用程序中, 你可以有效管理你的数据和高效率的读/写操作。
W3C主推的离线数据库类型,逐渐替代Web SQL类型数据库,更新效率高并不断完善。
工作在异步模式下执行每步操作。让你使用高效率的的JavaScript事件驱动模块
现在我们来尝试使用这个IndexDB:
1、初始化声明

1 var dbName = "H5AppDB"; //数据库名称 2 var dbVersion = 2.0; //数据库版本 3 var tablename = "todo"; //表名
2、初始并实例化IndexDB数据上下文

1 //定义一个IndexDB方法集合对象
2 var H5AppDB = {};
3
4 //实例化IndexDB数据上下文,这边根据浏览器类型来做选择
5 var indexedDB = window.indexedDB || window.webkitIndexedDB ||window.mozIndexedDB;
6
7 if ('webkitIndexedDB' in window) {
8 window.IDBTransaction = window.webkitIDBTransaction;
9 window.IDBKeyRange = window.webkitIDBKeyRange;
10 }
11
12 H5AppDB.indexedDB = {};
13 H5AppDB.indexedDB.db = null;
14
15 //错误信息,打印日志
16 H5AppDB.indexedDB.onerror = function (e) {
17 log.debug(e);
18 };
3、打开数据库,初始化数据库,并创建存储对象

1 H5AppDB.indexedDB.open = function () {
2
3 //初始IndexDB
4 var request = indexedDB.open(dbName, dbVersion);
5
6 request.onsuccess = function (e) {
7 // Old api: var v = "2-beta";
8 log.debug("success to open DB: " + dbName);
9 H5AppDB.indexedDB.db = e.target.result;
10 var db = H5AppDB.indexedDB.db;
11 if (db.setVersion) {
12 console.log("in old setVersion: " + db.setVersion);
13 if (db.version != dbVersion) {
14 var req = db.setVersion(dbVersion);
15 req.onsuccess = function () {
16 if (db.objectStoreNames.contains(tablename)) {
17 db.deleteObjectStore(tablename);
18 }
19 var store = db.createObjectStore(tablename, { keyPath: "timeStamp" });//keyPath:主键,唯一性
20
21 var trans = req.result;
22 trans.oncomplete = function (e) {
23 console.log("== trans oncomplete ==");
24 H5AppDB.indexedDB.getAllTodoItems();
25 }
26 };
27 }
28 else {
29 H5AppDB.indexedDB.getAllTodoItems();
30 }
31 }
32 else {
33 H5AppDB.indexedDB.getAllTodoItems();
34 }
35 }
36
37 //如果版本不一致,执行版本升级的操作
38 request.onupgradeneeded = function (e) {
39 log.debug("going to upgrade our DB!");
40
41 H5AppDB.indexedDB.db = e.target.result;
42 var db = H5AppDB.indexedDB.db;
43 if (db.objectStoreNames.contains(tablename)) {
44 db.deleteObjectStore(tablename);
45 }
46
47 var store = db.createObjectStore(tablename, { keyPath: "timeStamp" });//NoSQL类型数据库中必须的主键,唯一性
48
49 H5AppDB.indexedDB.getAllTodoItems();
50 }
51
52 request.onfailure = H5AppDB.indexedDB.onerror;
53 };
4、获取对象信息,并进行轮询读取,然后绑定到页面

1 //、获取对象信息
2 H5AppDB.indexedDB.getAllTodoItems = function () {
3
4 var todos = document.getElementById("todoItems");
5 todos.innerHTML = "";
6
7
8
9 var db = H5AppDB.indexedDB.db;
10 var trans = db.transaction([tablename], "readwrite");//通过事物开启对象
11 var store = trans.objectStore(tablename);//获取到对象的值
12
13 // Get everything in the store;
14
15 var keyRange = IDBKeyRange.lowerBound(0);
16 var cursorRequest = store.openCursor(keyRange);//开启索引为0的表
17
18 cursorRequest.onsuccess = function (e) {
19
20 var result = e.target.result;
21
22 if (!!result == false)
23 return;
24
25 renderTodo(result.value);
26 result.continue();//这边执行轮询读取
27 };
28
29 cursorRequest.onerror = H5AppDB.indexedDB.onerror;
30 };
31
32 //绑定数据
33 function renderTodo(row) {
34 var todos = document.getElementById("todoItems");
35 var li = document.createElement("li");
36 var a = document.createElement("a");
37 var t = document.createTextNode(row.text);
38
39 a.addEventListener("click", function() {
40 H5AppDB.indexedDB.deleteTodo(row.timeStamp);
41 }, false);
42
43 a.textContent = " [Delete]";
44 li.appendChild(t);
45 li.appendChild(a);
46 todos.appendChild(li);
47 };
效果如下:

5、添加数据对象

1 //4、添加数据对象
2 H5AppDB.indexedDB.addTodo = function (todoText) {
3 var db = H5AppDB.indexedDB.db;
4 var trans = db.transaction([tablename], "readwrite");
5 var store = trans.objectStore(tablename);
6
7 var newArray = new Array("wzh","374532");
8
9 //数据以对象形式保存,体现NoSQL类型数据库的灵活性
10 var data = {
11 "text": todoText,
12 "timeStamp": new Date().getTime(),
13 "obj":newArray
14 };
15
16 var request = store.put(data);//保存数据
17
18 request.onsuccess = function (e) {
19 H5AppDB.indexedDB.getAllTodoItems();
20 };
21
22 request.onerror = function (e) {
23 log.debug("Error Adding: ", e);
24 };
25 };
26 function addTodo() {
27 var todo = document.getElementById("todo");
28 H5AppDB.indexedDB.addTodo(todo.value);
29 todo.value = "";
30 }
可以随意添加BJson格式的对象,体现NoSQl类型数据库的优越性...

6、删除数据对象(根据主键删除)

1
2 // 删除数据对象
3 H5AppDB.indexedDB.deleteTodo = function(id) {
4 var db = H5AppDB.indexedDB.db;
5 var trans = db.transaction([tablename], "readwrite");
6 var store = trans.objectStore(tablename);
7
8 var request = store.delete(id);//根据主键来删除
9
10 request.onsuccess = function(e) {
11
12 H5AppDB.indexedDB.getAllTodoItems();
13 alert("删除成功");
14 };
15
16 request.onerror = function(e) {
17 log.debug("Error Adding: ", e);
18 };
19 };
W3C已经停止了对Web SQL 的更新,会更加完善对Index的规范草案和标准,所以以后的HTML5应用,有用到离线端数据库这一块,建议优先考虑IndexDB...
来源:https://www.cnblogs.com/wzh2010/p/3220906.html
