HTML5项目笔记10:使用HTML5 IndexDB设计离线数据库
之前的文章(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...