订阅软件研发RSS CSDN首页> 软件研发

HTML5 Web SQL Database与Indexed Database的CRUD操作

发表于2012-10-23 16:06| 次阅读| 来源developerWorks| 0 条评论| 作者姜俊杰

摘要:Web SQL Database和Indexed Database都是在客户端存储大量结构化数据的解决方案。Web SQL Database 实现了传统的基于SQL语句的数据库操作,而Indexed Database实现了NoSQL的存储方式。本文主要对比两者在CRUD操作方面的实现方法,按照本文所述读者可以详细了解两者异同。

HTML5 简介

HTML标准自1999年12月发布的HTML 4.01后,后继的HTML 5和其它标准被束之高阁,为了推动Web标准化运动的发展,一些公司联合起来,成立了一个叫做Web Hypertext Application Technology Working Group(Web 超文本应用技术工作组 - WHATWG)的组织,HTML5草案的前身名为Web Applications 1.0,於2004年被WHATWG提出,於2007年被W3C接纳,并成立了新的HTML工作团队。HTML 5的第一份正式草案已于2008年1月22日公布。HTML 5有两大特点:首先,强化了Web网页的表现性能。其次,追加了本地数据库等Web应用的功能。HTML5规范可以参考W3C官方网站

Web SQL Database和Indexed Database简介

Web SQL Database介绍

Web SQL Database API实际上未包含在HTML 5规范之中,它是一个独立的规范,它引入了一套使用SQL操作客户端数据库的API,这些API有同步的,也有异步的,同步版本的API只在工作线程(Worker Threads)上有用,由于并不是所有的浏览器都支持工作线程,一般情况下,都会使用异步API。它的核心方法有三个:openDatabase,transaction和executeSql。这些API已经被广泛的实现在了不同的浏览器里,尤其是手机端浏览器。虽然W3C官方在2011年11月声明已经不再维护Web SQL Database规范,但由于其广泛的实现程度,了解这些API对 Web开发还是非常有必要的。详细的Web SQL Database规范可以参考官方网站

Indexed Database介绍

Indexed Database,也可简称为IndexedDB(以前被称作WebSimpleDB),同样是一个Web客户端存储结构化数据的规范,在2009年由Oracle提出。如果说Web SQL Databae在客户端实现了传统的SQL数据库操作,那么Indexed Database更类似于NoSQL的形式来操作数据库,其中最重要的是Indexed Database不使用SQL作为查询语言。其数据存储可以不需要固定的表格模式,也经常会避免使用SQL的JOIN操作,并且一般具有水平可扩展性。目前W3C官方也把焦点投到对Indexed Database规范的制定当中来,而Microsoft和Mozilla是对这个规范重要的两个推动者,Firefox 4以上已经部分实现了Indexed DB API,并且IE 10中也将实现Indexed DB API。由于在手机等移动设备的浏览器中都没有实现Indexed DB API,所以其还有一定的局限性,但这并不妨碍它作为未来的HTML5的焦点而存在。详细的Indexed Database规范可以参考官方网站

浏览器对Web SQL Database和Indexed Database支持情况

表1.Web SQL Databse

Web SQL Databse

表 2.Indexed Databse

Indexed Databse

浏览器对Web SQL Database和Indexed Database支持的更详细信息可以参考网站When can I use...

Web SQL Database和Indexed Database的CRUD操作

本文以网上购物中的购物车为例,在场景中,用户可以添加多个商品到购物车,并且可以在购物车中进行删除修改等操作。而购物车的数据用户希望关闭浏览器后仍然存在,以便下 次用户再次打开此网站,仍可以看到这些购物车中的商品。这个场景比较适合用客户端数据库存储购物车中的商品,因为这些商品是结构化的数据,并且购物车中可能会存在大量商品。以下示例 code 在 Chrome 16.0 中通过测试。

1.创建数据库以及相应的表

在Web SQL Database中,由于内嵌的是SQLite数据库,所以仍需用SQL语句创建表 , 而列的数据类型可以参考SQLite数据库支持的数据类型。应用Web SQL Database API提供的OpenDatabase方法创建ShoppingCartDB数据库,并且应用传统的CREATE TABLE SQL句法创建ShoppingCart表。

清单1. Web SQL Database创建操作

  1. var dbInfo={   
  2.      dbName:"ShoppingCartDB",  // 名称  
  3.     dbVersion:"0.1", // 版本  
  4.     dbDisplayName:"Shopping Cart Database", // 显示名称  
  5.     dbEstimatedSize:10*11024*1024  // 大小 (byte)   
  6.  };   
  7.           
  8.  var db;   
  9.  function createDB(){   
  10.      db = window.openDatabase(dbInfo.dbName , dbInfo.dbVersion ,   
  11.          dbInfo.dbDisplayName , dbInfo.dbEstimatedSize);   
  12.  }   
  13.  
  14.  function dbError(tx, error){   
  15.      console.error(error);   
  16.  }   
  17.  
  18.  function createShoppingCartTable(){   
  19.      db.transaction(function(tx){   
  20.      tx.executeSql(   
  21.         "CREATE TABLE IF NOT EXISTS ShoppingCart " +   
  22.         "(Id TEXT PRIMARY KEY, Name TEXT, Price REAL,Count INTEGER,Desc TEXT)", [],  
  23.          function(){ console.log('ShoppingCart database created successfully!' ); },   
  24.          dbError   
  25.          );   
  26.      });   
  27.  }  

在Indexed Database中,ObjectStore代替了传统的表概念。每个ObjectStore相当于一个key和value的集合,key相当于传统数据库表中的主键,每个数据库可以有多个 ObjectStore。创建数据库时需要使用Indexed Database API的open方法,创建ShoppingCartDB,并且调用createObjectStore方法创建ShoppingCart ObjectStore。

清单 2.Indexed Database创建操作

  1. var dbInfo={   
  2.      dbName:"ShoppingCartDB",  // 名称  
  3.     dbVersion:"0.1"// 版本  
  4.  };   
  5.           
  6.  var db;   
  7.  var indexedDB = window.indexedDB || window.webkitIndexedDB;   
  8.  
  9.  if ('webkitIndexedDB' in window) {   
  10.      windowwindow.IDBTransaction = window.webkitIDBTransaction;   
  11.      windowwindow.IDBKeyRange = window.webkitIDBKeyRange;   
  12.  }   
  13.  
  14.  function createDBAndShoppingCartTable(){   
  15.      var request = indexedDB.open(dbInfo.dbName);   
  16.      request.onsuccess = function(evt) {   
  17.          db = evt.target.result;   
  18.          // 只能在 setVersion 事务中创建 Object Stores;   
  19.          if (dbInfo.dbVersion!= db.version) {   
  20.              var setVReq = db.setVersion(dbInfo.dbVersion);   
  21.              // onsuccess 方法是唯一创建 Object Stores 的地方  
  22.              setVReq.onerror = dbError;   
  23.              setVReq.onsuccess = function() {   
  24.                  if(db.objectStoreNames.contains("ShoppingCart")) {   
  25.           db.deleteObjectStore("ShoppingCart");   
  26.                  }   
  27.                  db.createObjectStore("ShoppingCart",{keyPath: "id"});  
  28.                  refreshShoppingCart();   
  29.              };   
  30.          }   
  31.          else{   
  32.              refreshShoppingCart();   
  33.          }   
  34.      };   
  35.      request.onerror = dbError;   
  36.  }   
  37.  
  38.  function dbError(error){   
  39.      console.error(error);   
  40.  }  

2.添加商品数据

添加商品界面

在Web SQL Database中仍需使用传统的SQL INSERT操作,向表中添加数据。Web SQL Database API提供的方法可以使用参数形式向表中插入数据。

清单 3.Web SQL Database添加数据操作

  1. function insertDataToShoppingCart(data){   
  2.      db.transaction(function(tx){   
  3.          tx.executeSql("INSERT INTO ShoppingCart " +   
  4.             "(Id, Name,Price,Count,Desc) VALUES (?,?,?,?,?)" ,   
  5.              [data.id, data.name,data.price,data.count,data.desc],   
  6.              function(tx, result){   
  7.                  refreshShoppingCart();   
  8.              },   
  9.              dbError   
  10.          );   
  11.      });   
  12.  }   
  13.       

在Indexed Database中需要使用ObjectStore的put方法,把key和value添加到ObjectStore中。

清单 4.Indexed Database添加数据操作

  1. //data 是个 JavaScript 对象结构是 {id:String,item:Object}   
  2.  //data 中的 item 属性是个对象,包括商品的信息,例如名称,价格等  
  3.  function insertOrUpdateDataToShoppingCart(data){   
  4.      console.log("insertOrUpdateDataToShoppingCart",data);   
  5.      var trans = db.transaction(["ShoppingCart"], IDBTransaction.READ_WRITE);   
  6.      var store = trans.objectStore("ShoppingCart");   
  7.      var request = store.put(data);   
  8.      request.onsuccess = function(e) {   
  9.          refreshShoppingCart();   
  10.      };   
  11.      request.onerror = dbError;   
  12.  }  

3.读取商品数据

购物车列表界面

购物车列表界面

在Web SQL Database可以使用SQL的SELECT语句查询出所有的记录,然后遍历行数据,获取所有商品信息。

清单 5.Web SQL Database读取数据操作

  1. function refreshShoppingCart(){   
  2.      dojo.byId("shoppingCartTableData").innerHTML="";   
  3.      db.transaction(function(tx){   
  4.          tx.executeSql("SELECT * FROM ShoppingCart" ,[],   
  5.              function(tx, result){   
  6.                  for(var i=0;i<result.rows.length;i++){    
  7.           var item=result.rows.item(i);   
  8.           var shoppingCart = dojo.byId("shoppingCartTableData");   
  9.           var tableRow = dojo.create("tr",{},shoppingCart);   
  10.           dojo.create("td",{"innerHTML":item.Name},tableRow);   
  11.           dojo.create("td",{"innerHTML":item.Price},tableRow);   
  12.           dojo.create("td",{"innerHTML":item.Count},tableRow);   
  13.           dojo.create("td",{"innerHTML":item.Desc},tableRow);   
  14.           dojo.create("td",{"innerHTML":item.Price*item.Count},tableRow);   
  15.           var actions = dojo.create("td",{},tableRow);   
  16.           var btnDelete = new dijit.form.Button({   
  17.                         "label":"删除",   
  18.                         "onClick":(function(id){   
  19.                   return function(){deleteDataFromShoppingCart(id)}}   
  20.               )(item.Id)   
  21.           });   
  22.           var btnUpdate = new dijit.form.Button({   
  23.                          "label":"更新",   
  24.                          "onClick":(function(item){return function(){   
  25.                   showUpdateDataDialog(   
  26.                       {id:item.Id,name:item.Name,price:item.Price,   
  27.                       count:item.Count,desc:item.Desc});   
  28.               }})(item)   
  29.           });   
  30.           actions.appendChild(btnDelete.domNode);   
  31.           actions.appendChild(btnUpdate.domNode);   
  32.                  }   
  33.              },   
  34.              dbError   
  35.          );   
  36.      });   
  37.  }  

在Indexed Database中需要根据其提供的查询API进行数据的查询。这里使用IDBKeyRange这个对象确定需要查询数据的上下限,在调用ObjectStore提供的openCursor方法,传进 IDBKeyRange对象作为参数。然后像使用数据库游标一样,在onsuccess回调方法中,获取数据对象,每次获取下一行数据时需要调用result对象的continue方法。

清单 6.Indexed Database读取数据操作

  1. function refreshShoppingCart(){   
  2.      dojo.byId("shoppingCartTableData").innerHTML="";   
  3.      var trans = db.transaction(["ShoppingCart"], IDBTransaction.READ_ONLY);   
  4.      var store = trans.objectStore("ShoppingCart");   
  5.      var keyRange = IDBKeyRange.lowerBound(0);// 查询所有数据  
  6.      var cursorReq = store.openCursor(keyRange);   
  7.      cursorReq.onsuccess = function(evt) {   
  8.          var result = evt.target.result;   
  9.          if(!result)return;// 没有数据返回  
  10.          var item = result.value.item   
  11.          var shoppingCart = dojo.byId("shoppingCartTableData");   
  12.          var tableRow = dojo.create("tr",{},shoppingCart);   
  13.          dojo.create("td",{"innerHTML":item.name},tableRow);   
  14.          dojo.create("td",{"innerHTML":item.price},tableRow);   
  15.          dojo.create("td",{"innerHTML":item.count},tableRow);   
  16.          dojo.create("td",{"innerHTML":item.desc},tableRow);   
  17.          dojo.create("td",{"innerHTML":item.price*item.count},tableRow);   
  18.          var actions = dojo.create("td",{},tableRow);   
  19.          var btnDelete = new dijit.form.Button({   
  20.             "label":"删除",   
  21.             "onClick":(function(id){   
  22.                  return function(){deleteDataFromShoppingCart(id)}}   
  23.              )(result.value.id)   
  24.          });   
  25.          var btnUpdate = new dijit.form.Button({   
  26.             "label":"更新",   
  27.             "onClick":(function(item){return function(){   
  28.           showUpdateDataDialog({id:result.value.id,name:item.name,   
  29.           price:item.price,count:item.count,desc:item.desc});   
  30.              }})(item)   
  31.          });   
  32.          actions.appendChild(btnDelete.domNode);   
  33.          actions.appendChild(btnUpdate.domNode);   
  34.          result.continue();// 继续读取下一行操作  
  35.      };   
  36.      cursorReq.onerror = dbError;   
  37.  }  

4.更新商品数据

更新商品信息界面

更新商品信息界面

在Web SQL Database 需要使用传统的 QL UPDATE 作更新数据库表中的数据。

清单 7.Web SQL Database更新数据操作

  1. function updateDataToShoppingCart(data){   
  2.      console.log("updateDataToShoppingCart",data);   
  3.      db.transaction(function(tx){   
  4.          tx.executeSql("UPDATE ShoppingCart SET " +   
  5.             "Name = ?, Price = ? , Count = ?,Desc = ? WHERE Id = ?" ,   
  6.              [data.name,data.price,data.count,data.desc,data.id],   
  7.              function(tx, result){   
  8.                  refreshShoppingCart();   
  9.              },   
  10.              dbError   
  11.          );   
  12.      });   
  13.  }  

在Indexed Database操作中,更新数据和添加数据的方法是一样,如果data中的id在ObjectStore中已经存在了,将进行更新操作,否则将添加新数据

清单 8.Indexed Database更新数据操作

  1. function insertOrUpdateDataToShoppingCart(data){   
  2.      console.log("insertOrUpdateDataToShoppingCart",data);   
  3.      var trans = db.transaction(["ShoppingCart"], IDBTransaction.READ_WRITE);   
  4.      var store = trans.objectStore("ShoppingCart");   
  5.      var request = store.put(data);   
  6.      request.onsuccess = function(e) {   
  7.          refreshShoppingCart();   
  8.      };   
  9.      request.onerror = dbError;   
  10.  } 

4.删除商品数据

在Web SQL Database中需要使用传统的SQL DELETE操作删除数据库中表记录。

清单 9.Web SQL Database删除数据操作

  1. function deleteDataFromShoppingCart(id){   
  2.  console.log("deleteDataFromShoppingCart",id);   
  3.  db.transaction(function(tx){   
  4.      tx.executeSql("DELETE FROM ShoppingCart WHERE Id = ?" ,   
  5.          [id],   
  6.          function(tx, result){   
  7.              refreshShoppingCart();   
  8.          },   
  9.          dbError   
  10.      );   
  11.  });   
  12. }  

在Indexed Database ,需要使用API中ObjectStore的delete方法,传进key值作为参数,删除相应的记录。

清单 10.Indexed Database删除数据操作

  1. function deleteDataFromShoppingCart(id){   
  2.  console.log("deleteDataFromShoppingCart",id);   
  3.  var trans = db.transaction(["ShoppingCart"], IDBTransaction.READ_WRITE);   
  4.  var store = trans.objectStore("ShoppingCart");   
  5.  var request = store.delete(id);   
  6.  request.onsuccess = function(e) {   
  7.      refreshShoppingCart();   
  8.  };   
  9.  request.onerror = dbError;   
  10. }  

结束语

本文基于购物车示例详细介绍了Web SQL Database和Indexed Database的CRUD操作,从代码简洁程度来看,Indexed Database的操作更清晰。但Web SQL Database的操作方式对传统开发人员来说更友好。由于在不同的平台上浏览器对两种客户端数据库的支持程度的差异,分别掌握两种客户端数据库的操作方法还是非常有必要的。 随着HTML5规范的发展,相信未来在客户端存储数据将会越来越容易。

来自:developerWorks中文站

0
0
HTML5 Web SQL Database与Indexed Database的CRUD操作