(转)HTML 5离线存储之Web SQL

原文:http://developer.51cto.com/art/201106/267357.htm


HTML 5离线存储之Web SQL

2011-06-07 15:14 kkun kkun的博客 字号:T | T

WebDatabase
规范中说这份规范不再维护了,原因是同质化(几乎实现者都选择了Sqlite),
且不说这些,单看在HTML5中如何实现离线数据的CRUD,最基本的用法(入门级别)

AD:
51CTO学院:IT精品课程在线看!

本篇没有考虑异步,多线程及SQL注入

WebDatabase 规范中说这份规范不再维护了,原因是同质化(几乎实现者都选择了Sqlite),

且不说这些,单看在HTML5中如何实现离线数据的CRUD,最基本的用法(入门级别)

1,打开数据库

2,创建表

3,新增数据

4,更新数据

5,读取数据

6,删除数据

事实上,关键点在于如何拿到一个可执行SQL语句的上下文,

像创建表,删除表,CRUD操作等仅区别于SQL语句的写法.OK,貌似"SqlHelper"啊,换个名字,dataBaseOperator就它了

executeReader,executeScalar两个方法与executeNonQuery严重同质,

下边的代码产生定义了我们的dataBaseOperator"类",第二行

3-5行则定义打开数据库连接方法,"类方法",效果类似C#中的静态方法,直接类名.方法调用

6-15行则定义executeNonQuery方法,意指查询数据库,与executeReader方法和executeScalar方法同质,均可返回记录集

整个
dataBaseOperator就完整了,很简单,唯一要指出的是,测试以下代码时请选择一个支持HTML5的浏览器!如Google
Chrome

  1. //TODO;SQL注入

  2. function dataBaseOperator() {};

  3. dataBaseOperator.openDatabase = function () {

  4. return window.openDatabase("dataBaseUserStories", "1.0", "dataBase used for user stories", 2 * 1024 * 1024);

  5. }

  6. dataBaseOperator.executeNonQuery = function (sql, parameters, callback) {

  7. var db = this.openDatabase();

  8. db.transaction(function (trans) {

  9. trans.executeSql(sql, parameters, function (trans, result) {

  10. callback(result);

  11. }, function (trans, error) {

  12. throw error.message;

  13. });

  14. });

  15. }

  16. dataBaseOperatordataBaseOperator.executeReader = dataBaseOperator.executeNonQuery;

  17. dataBaseOperatordataBaseOperator.executeScalar = dataBaseOperator.executeNonQuery;

有了"SqlHeper",再看业务处理层(Business Logic Layer)

业务处理类包括了创建表,删除表,新增记录,删除记录以及读取记录,这里没有写更新,实际上先删后增一样滴,即使要写也不复杂

  1. function userStoryProvider() {

  2. this.createUserStoryTable = function () {

  3. dataBaseOperator.executeNonQuery("CREATE TABLE tbUserStories(id integer primary key autoincrement,role,ability,benefit,name,importance,estimate,notes)");

  4. };

  5. this.dropUserStoryTable = function () {

  6. dataBaseOperator.executeNonQuery("DROP TABLE tbUserStories");

  7. };

  8. this.addUserStory = function (role, ability, benefit, name, importance, estimate, notes) {

  9. dataBaseOperator.executeNonQuery("INSERT INTO tbUserStories(role,ability,benefit,name,importance,estimate,notes) SELECT ?,?,?,?,?,?,?",

  10. [role, ability, benefit, name, importance, estimate, notes], function (result) {

  11. //alert("rowsAffected:" + result.rowsAffected);

  12. });

  13. };

  14. this.removeUserStory = function (id) {

  15. dataBaseOperator.executeNonQuery("DELETE FROM tbUserStories WHERE id = ?", [id], function (result) {

  16. //alert("rowsAffected:" + result.rowsAffected);

  17. });

  18. };

  19. this.loadUserStories = function (callback) {

  20. dataBaseOperator.executeReader("SELECT * FROM tbUserStories", [], function (result) {

  21. callback(result);

  22. });

  23. //result.insertId,result.rowsAffected,result.rows24      };

  24. }

createUserStoryTable,dropUserStoryTable,addUserStory,removeUserStory又是严重同质,不说了,仅SQL语句不同而已

但loadUserStories与上述四个方法均不同,是因为它把SQLResultSetRowList返回给了调用者,这里仍然是简单的"转发",页面在使用的时候需要首先创建provider实例(使用类似C#中的类实例上的方法调用)

  1. var _userStoryProvider = new userStoryProvider();

之后就可以调用该实例的方法了,仅举个例子,具体代码省去

  1. function loadUserStory() {

  2. try {

  3. _userStoryProvider.loadUserStories(function (result) {

  4. var _userStories = new Array();

  5. for (var i = 0; i < result.rows.length; i++) {

  6. var o = result.rows.item(i);

  7. var _userStory = new userStory(o.id, o.name, o.role, o.ability, o.benefit, o.importance, o.estimate, o.notes);

  8. _userStories.push(_userStory);

  9. }//...

  10. } catch (error) {

  11. alert("_userStoryProvider.loadUserStories:" + error);

  12. }}

得到_userStories这个数组后,就没有下文了,是自动创建HTML还是绑定到EXT,发挥想象力吧...继续

userStory是一个自定义的"Model" "类"·

  1. function userStory(id, name, role, ability, benefit, importance, estimate, notes) {

  2. this.id = id;

  3. this.name = name;

  4. this.role = role;

  5. this.ability = ability;

  6. this.benefit = benefit;

  7. this.importance = importance;

  8. this.estimate = estimate;

  9. this.notes = notes;

  10. };

最后贴出应用的代码,业务相关的代码,不看也罢,谁家与谁家的都不同

  1. /*

  2. http://stackoverflow.com/questions/2010892/storing-objects-in-html5-localstorage

  3. http://www.w3.org/TR/webdatabase/#sqlresultset

  4. http://html5doctor.com/introducing-web-sql-databases/

  5. http://stackoverflow.com/questions/844885/sqlite-insert-into-with-unique-names-getting-id

  6. */

  7. var _userStoryProvider = new userStoryProvider();

  8. $(document).ready(function () {

  9. loadUserStory();
  10. /* 添加用户故事 */

  11. $("#btnAdd").click(function () {

  12. var item = { role: $("#role").val(), ability: $("#ability").val(), benefit: $("#benefit").val(), name: $("#Name").val(), importance: $("#Importance").val(), estimate: $("#Estimate").val(), notes: $("#Notes").val() };

  13. try {

  14. _userStoryProvider.addUserStory(item.role, item.ability, item.benefit, item.name, item.importance, item.estimate, item.notes);

  15. loadUserStory();

  16. } catch (error) {

  17. alert("_userStoryProvider.addUserStory:" + error);

  18. }

  19. });
  20. /* 创建用户故事表 */

  21. $("#btnCreateTable").click(function () {          try {

  22. _userStoryProvider.createUserStoryTable();

  23. } catch (error) {

  24. alert("_userStoryProvider.createUserStoryTable:" + error);

  25. }

  26. });
  27. /* 删除用户故事表 */

  28. $("#btnDropTable").click(function () {

  29. try {

  30. _userStoryProvider.dropUserStoryTable();

  31. } catch (error) {

  32. alert("_userStoryProvider.dropUserStoryTable:" + error);

  33. }

  34. });

  35. });
  36. /* 加载用户故事 */

  37. function loadUserStory() {

  38. try {

  39. _userStoryProvider.loadUserStories(function (result) {

  40. var _userStories = new Array();

  41. for (var i = 0; i < result.rows.length; i++) {

  42. var o = result.rows.item(i);

  43. var _userStory = new userStory(o.id, o.name, o.role, o.ability, o.benefit, o.importance, o.estimate, o.notes);

  44. _userStories.push(_userStory);

  45. }
  46. if (!_userStories) return;

  47. var table = document.getElementById("user_story_table");

  48. if (!table) return;

  49. var _trs = table.getElementsByTagName("tr");

  50. var _len = _trs.length;

  51. for (var i = 0; i < _len; i++) {

  52. table.removeChild(_trs[i]);

  53. }

  54. {

  55. var tr = document.createElement("tr");

  56. tr.setAttribute("class", "product_backlog_row header");

  57. {

  58. tr.appendChild(CreateTd("id", "id"));

  59. tr.appendChild(CreateTd("name", "name"));

  60. tr.appendChild(CreateTd("importance", "importance"));

  61. tr.appendChild(CreateTd("estimate", "estimate"));

  62. tr.appendChild(CreateTd("description", "role"));

  63. tr.appendChild(CreateTd("notes", "notes"));

  64. tr.appendChild(CreateTd("delete", "delete"));

  65. };

  66. table.appendChild(tr);

  67. }

  68. for (var i = 0; i < _userStories.length; i++) {

  69. CreateRow(table, _userStories[i]);

  70. }

  71. });

  72. } catch (error) {

  73. alert("_userStoryProvider.loadUserStories:" + error);

  74. }

  75. }

  76. function CreateRow(table, userStory) {

  77. if (!table) return;

  78. if (!userStory) return;

  79. {

  80. var tr = document.createElement("tr");

  81. tr.setAttribute("class", "product_backlog_row");

  82. {

  83. tr.appendChild(CreateTd("id", userStory.id));

  84. tr.appendChild(CreateTd("name", userStory.name));

  85. tr.appendChild(CreateTd("importance", userStory.importance));

  86. tr.appendChild(CreateTd("estimate", userStory.estimate));

  87. tr.appendChild(CreateTd("description", userStory.role));

  88. tr.appendChild(CreateTd("notes", userStory.notes));

  89. tr.appendChild(CreateDeleteButton("delete_button", userStory.id));

  90. };

  91. table.appendChild(tr);

  92. }

  93. }

  94. function CreateTd(name, value) {

  95. var td = document.createElement("td");

  96. td.setAttribute("class", "user_story " + name);

  97. td.innerText = value;

  98. return td;

  99. };

  100. function CreateDeleteButton(name, id) {

  101. var td = document.createElement("td");

  102. td.setAttribute("class", "user_story " + name);

  103. /* 删除用户故事 */

  104. td.innerHTML = "<a href=\"###\" title=\"delete\" onclick=\"javascript:_userStoryProvider.removeUserStory(\‘" + id + "‘);removeRow(this);\">>>delete</a>";

  105. return td;

  106. }

  107. function removeRow(obj) {

  108. document.getElementById("user_story_table").deleteRow(obj.parentNode.parentNode.rowIndex);

  109. //obj.parentNode.parentNode.removeNode(true);

  110. }

看完代码复习下基本功课

1,WindowDatabase接口,注意openDatabase方法

  1. [Supplemental, NoInterfaceObject]

  2. interface WindowDatabase {

  3. Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback);};

  4. Window implements WindowDatabase;

  5. [Supplemental, NoInterfaceObject]

  6. interface WorkerUtilsDatabase {

  7. Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback);  DatabaseSync openDatabaseSync(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback);};

  8. WorkerUtils implements WorkerUtilsDatabase;

  9. [Callback=FunctionOnly, NoInterfaceObject]

  10. interface DatabaseCallback {

  11. void handleEvent(in Database database);

  12. };

2,SQLTransaction接口,关注executeSql方法

  1. typedef sequence<any> ObjectArray;

  2. interface SQLTransaction {

  3. void executeSql(in DOMString sqlStatement, in optional ObjectArray arguments, in optional SQLStatementCallback callback, in optional SQLStatementErrorCallback errorCallback);};

  4. [Callback=FunctionOnly, NoInterfaceObject]

  5. interface SQLStatementCallback {

  6. void handleEvent(in SQLTransaction transaction, in SQLResultSet resultSet);};

  7. [Callback=FunctionOnly, NoInterfaceObject]

  8. interface SQLStatementErrorCallback {

  9. boolean handleEvent(in SQLTransaction transaction, in SQLError error);

  10. };

3,最后看下SQLResultSetRowList定义

  1. interface SQLResultSetRowList {

  2. readonly attribute unsigned long length;

  3. getter any item(in unsigned long index);

  4. };

和SQLResultSet定义

  1. interface SQLResultSet {

  2. readonly attribute long insertId;

  3. readonly attribute long rowsAffected;

  4. readonly attribute SQLResultSetRowList rows;

  5. };

(转)HTML 5离线存储之Web SQL,布布扣,bubuko.com

时间: 2024-10-25 14:48:12

(转)HTML 5离线存储之Web SQL的相关文章

HTML5 离线存储之Web SQL

HTML5 在离线存储之Web SQL 本篇没有考虑异步,多线程及SQL注入 WebDatabase 规范中说这份规范不再维护了,原因是同质化(几乎实现者都选择了Sqlite), 且不说这些,单看在HTML5中如何实现离线数据的CRUD,最基本的用法(入门级别)  1,打开数据库 2,创建表 3,新增数据 4,更新数据 5,读取数据 6,删除数据 事实上,关键点在于如何拿到一个可执行SQL语句的上下文, 像创建表,删除表,CRUD操作等仅区别于SQL语句的写法.OK,貌似"SqlHelper&q

(转)HTML5开发学习(3):本地存储之Web Sql Database

原文:http://www.cnblogs.com/xumingxiang/archive/2012/03/25/2416386.html HTML5开发学习(3):本地存储之Web Sql Database(附源码) Posted on 2012-03-25 14:03 祥叔 阅读(0) 评论(0)  编辑 收藏 接着上一篇,这节介绍Html5 本地存储中的一个很重要的概念--Web Sql Database ,正因为本人觉得这个很重要,所有独立出来重点介绍.即时你完全没听说过这个概念,望文生

前端存储之Web Sql Database

前言 在上一篇前端存储之indexedDB中说到,我们项目组要搞一个前后端分离的项目,要求在前端实现存储,我们首先找到了indexedDB,而我们研究了一段时间的indexedDB后,发现它并不是很适合我们的项目,原因文章后面会讲到,所以我们就继续找,于是我们就找到了Web Sql Database,发现这个前端数据库是比较适合我们的项目的,于是果断转投Web Sql Database的怀抱,找存储工具跟穿鞋一个道理,不在乎多炫酷,合适才是王道,要是因为不合适导致磨脚是走不长远的,既然找到了合适

html5 初试 Web SQL Database

Web SQL Database API不包含在html5规范中,它是一个独立的规范,它引入了一套使用 SQL 操作客户端数据库的 API.所有现代浏览器都支持此API.它使用的SQL是SQLite . html5 中使用 Local and session storage 本地存储非常的方便,键值对方式虽说是使用方便,但对一些大量的数据结构处理就力有不及了,而Web SQL Database正适合这种类型的数据存储. Web SQL Database 是异步的. 连接/创建Database:

HTML5 Web 客户端五种离线存储方式汇总

最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利用了Cookie.WebStorage.IndexedDB以及FileSystem四种本地离线存储方式,对燃气监控系统的表计位置.朝向.开关以及表值等信息做了CURD的存取操作. HTML5的存储还有一种Web SQL Database方式,虽然还有浏览器支持,是唯一的关系数据库结构的存储,但W3C以及停止对其的维护和发展,所以这里我们也不再对其进行介绍:Bewa

Web离线存储的几种方式

随着HTML5的正式定稿,我们也可以大量使用HTML离线网络应用程序的特性. #1.Application Cache Application Cache 可以很简单让我们的WebApp具有离线的能力. 支持的浏览器:IE10+,FireFox,Chrome,Safari,Opera 优点: 离线浏览 -- 用户可以再离线时使用Application 速度 -- 由于缓存了资源,如果加载很快 减少服务端数据加载 -- 浏览器只需要从服务器加载更新过的数据 缺点: Manifest文件有变化时才更

Html5 Web的5中离线存储方式之localStorage

Html5 Web的5中离线存储方式之localStorage 在HTML5越来越流行的今天,如果你还不知道离线存储,那就说明你落后了很多. HTML5的离线存储方式有多种:Web SQL Database.LocalStorage.Cookie.WebStorage.IndexedDB.FileSystem. Web SQL Database目前虽然还有浏览器支持,是唯一的关系数据库结构的存储,但W3C以及停止对其的维护和发展.我就不多说了. 今天我们主要看LocalStorage这种最简单的

localForage——轻松实现 Web 离线存储

localStorage 能够让你实现基本的数据存储,但它的速度慢,而且不能处理二进制数据.IndexedDB 和 WebSQL 是异步的,速度快,支持大数据集,但他们的API 使用起来有点复杂.不仅如此,IndexedDB 和 WebSQL 没有被所有的主流的浏览器厂商支持,这种情况最近也不太可能改变. Mozilla 开发了一个叫 localForage 的库 ,使得离线数据存储在任何浏览器都是一项容易的任务. localForage 是一个使用非常简单的 JavaScript 库的,提供了

Atitit.h5 web webview性能提升解决方案-----fileStrore缓存离线存储+http方案

1. 业务场景 android+webview h5 css背景图性能提升1 2. 根据标准,到目前为止,H5 一共有6种缓存机制,有些是之前已有,有些是 H5 才新加入的.1 2.1. 各种方案的比较,如下图2 3. Attilax的解决之道 file 缓存+http3 3.1. 图片的下载3 3.2. Jsbridge 4android5 3.3. http协议6 4. 参考8 1. 业务场景 android+webview h5 css背景图性能提升 图片的缓存大概儿需要500m的规模..