(转)HTML 5离线存储之Web SQL
原文:http://developer.51cto.com/art/201106/267357.htm
HTML 5离线存储之Web SQL
WebDatabase 规范中说这份规范不再维护了,原因是同质化(几乎实现者都选择了Sqlite), 且不说这些,单看在HTML5中如何实现离线数据的CRUD,最基本的用法(入门级别)
本篇没有考虑异步,多线程及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
- //TODO;SQL注入
- function dataBaseOperator() {};
- dataBaseOperator.openDatabase = function () {
- return window.openDatabase("dataBaseUserStories", "1.0", "dataBase used for user stories", 2 * 1024 * 1024);
- }
- dataBaseOperator.executeNonQuery = function (sql, parameters, callback) {
- var db = this.openDatabase();
- db.transaction(function (trans) {
- trans.executeSql(sql, parameters, function (trans, result) {
- callback(result);
- }, function (trans, error) {
- throw error.message;
- });
- });
- }
- dataBaseOperatordataBaseOperator.executeReader = dataBaseOperator.executeNonQuery;
- dataBaseOperatordataBaseOperator.executeScalar = dataBaseOperator.executeNonQuery;
有了"SqlHeper",再看业务处理层(Business Logic Layer)
业务处理类包括了创建表,删除表,新增记录,删除记录以及读取记录,这里没有写更新,实际上先删后增一样滴,即使要写也不复杂
- function userStoryProvider() {
- this.createUserStoryTable = function () {
- dataBaseOperator.executeNonQuery("CREATE TABLE tbUserStories(id integer primary key autoincrement,role,ability,benefit,name,importance,estimate,notes)");
- };
- this.dropUserStoryTable = function () {
- dataBaseOperator.executeNonQuery("DROP TABLE tbUserStories");
- };
- this.addUserStory = function (role, ability, benefit, name, importance, estimate, notes) {
- dataBaseOperator.executeNonQuery("INSERT INTO tbUserStories(role,ability,benefit,name,importance,estimate,notes) SELECT ?,?,?,?,?,?,?",
- [role, ability, benefit, name, importance, estimate, notes], function (result) {
- //alert("rowsAffected:" + result.rowsAffected);
- });
- };
- this.removeUserStory = function (id) {
- dataBaseOperator.executeNonQuery("DELETE FROM tbUserStories WHERE id = ?", [id], function (result) {
- //alert("rowsAffected:" + result.rowsAffected);
- });
- };
- this.loadUserStories = function (callback) {
- dataBaseOperator.executeReader("SELECT * FROM tbUserStories", [], function (result) {
- callback(result);
- });
- //result.insertId,result.rowsAffected,result.rows24 };
- }
createUserStoryTable,dropUserStoryTable,addUserStory,removeUserStory又是严重同质,不说了,仅SQL语句不同而已
但loadUserStories与上述四个方法均不同,是因为它把SQLResultSetRowList返回给了调用者,这里仍然是简单的"转发",页面在使用的时候需要首先创建provider实例(使用类似C#中的类实例上的方法调用)
- var _userStoryProvider = new userStoryProvider();
之后就可以调用该实例的方法了,仅举个例子,具体代码省去
- function loadUserStory() {
- try {
- _userStoryProvider.loadUserStories(function (result) {
- var _userStories = new Array();
- for (var i = 0; i < result.rows.length; i++) {
- var o = result.rows.item(i);
- var _userStory = new userStory(o.id, o.name, o.role, o.ability, o.benefit, o.importance, o.estimate, o.notes);
- _userStories.push(_userStory);
- }//...
- } catch (error) {
- alert("_userStoryProvider.loadUserStories:" + error);
- }}
得到_userStories这个数组后,就没有下文了,是自动创建HTML还是绑定到EXT,发挥想象力吧...继续
userStory是一个自定义的"Model" "类"·
- function userStory(id, name, role, ability, benefit, importance, estimate, notes) {
- this.id = id;
- this.name = name;
- this.role = role;
- this.ability = ability;
- this.benefit = benefit;
- this.importance = importance;
- this.estimate = estimate;
- this.notes = notes;
- };
最后贴出应用的代码,业务相关的代码,不看也罢,谁家与谁家的都不同
- /*
- http://stackoverflow.com/questions/2010892/storing-objects-in-html5-localstorage
- http://www.w3.org/TR/webdatabase/#sqlresultset
- http://html5doctor.com/introducing-web-sql-databases/
- http://stackoverflow.com/questions/844885/sqlite-insert-into-with-unique-names-getting-id
- */
- var _userStoryProvider = new userStoryProvider();
- $(document).ready(function () {
- loadUserStory();
- /* 添加用户故事 */
- $("#btnAdd").click(function () {
- var item = { role: $("#role").val(), ability: $("#ability").val(), benefit: $("#benefit").val(), name: $("#Name").val(), importance: $("#Importance").val(), estimate: $("#Estimate").val(), notes: $("#Notes").val() };
- try {
- _userStoryProvider.addUserStory(item.role, item.ability, item.benefit, item.name, item.importance, item.estimate, item.notes);
- loadUserStory();
- } catch (error) {
- alert("_userStoryProvider.addUserStory:" + error);
- }
- });
- /* 创建用户故事表 */
- $("#btnCreateTable").click(function () { try {
- _userStoryProvider.createUserStoryTable();
- } catch (error) {
- alert("_userStoryProvider.createUserStoryTable:" + error);
- }
- });
- /* 删除用户故事表 */
- $("#btnDropTable").click(function () {
- try {
- _userStoryProvider.dropUserStoryTable();
- } catch (error) {
- alert("_userStoryProvider.dropUserStoryTable:" + error);
- }
- });
- });
- /* 加载用户故事 */
- function loadUserStory() {
- try {
- _userStoryProvider.loadUserStories(function (result) {
- var _userStories = new Array();
- for (var i = 0; i < result.rows.length; i++) {
- var o = result.rows.item(i);
- var _userStory = new userStory(o.id, o.name, o.role, o.ability, o.benefit, o.importance, o.estimate, o.notes);
- _userStories.push(_userStory);
- }
- if (!_userStories) return;
- var table = document.getElementById("user_story_table");
- if (!table) return;
- var _trs = table.getElementsByTagName("tr");
- var _len = _trs.length;
- for (var i = 0; i < _len; i++) {
- table.removeChild(_trs[i]);
- }
- {
- var tr = document.createElement("tr");
- tr.setAttribute("class", "product_backlog_row header");
- {
- tr.appendChild(CreateTd("id", "id"));
- tr.appendChild(CreateTd("name", "name"));
- tr.appendChild(CreateTd("importance", "importance"));
- tr.appendChild(CreateTd("estimate", "estimate"));
- tr.appendChild(CreateTd("description", "role"));
- tr.appendChild(CreateTd("notes", "notes"));
- tr.appendChild(CreateTd("delete", "delete"));
- };
- table.appendChild(tr);
- }
- for (var i = 0; i < _userStories.length; i++) {
- CreateRow(table, _userStories[i]);
- }
- });
- } catch (error) {
- alert("_userStoryProvider.loadUserStories:" + error);
- }
- }
- function CreateRow(table, userStory) {
- if (!table) return;
- if (!userStory) return;
- {
- var tr = document.createElement("tr");
- tr.setAttribute("class", "product_backlog_row");
- {
- tr.appendChild(CreateTd("id", userStory.id));
- tr.appendChild(CreateTd("name", userStory.name));
- tr.appendChild(CreateTd("importance", userStory.importance));
- tr.appendChild(CreateTd("estimate", userStory.estimate));
- tr.appendChild(CreateTd("description", userStory.role));
- tr.appendChild(CreateTd("notes", userStory.notes));
- tr.appendChild(CreateDeleteButton("delete_button", userStory.id));
- };
- table.appendChild(tr);
- }
- }
- function CreateTd(name, value) {
- var td = document.createElement("td");
- td.setAttribute("class", "user_story " + name);
- td.innerText = value;
- return td;
- };
- function CreateDeleteButton(name, id) {
- var td = document.createElement("td");
- td.setAttribute("class", "user_story " + name);
- /* 删除用户故事 */
- td.innerHTML = "<a href=\"###\" title=\"delete\" onclick=\"javascript:_userStoryProvider.removeUserStory(\'" + id + "');removeRow(this);\">>>delete</a>";
- return td;
- }
- function removeRow(obj) {
- document.getElementById("user_story_table").deleteRow(obj.parentNode.parentNode.rowIndex);
- //obj.parentNode.parentNode.removeNode(true);
- }
看完代码复习下基本功课
1,WindowDatabase接口,注意openDatabase方法
- [Supplemental, NoInterfaceObject]
- interface WindowDatabase {
- Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback);};
- Window implements WindowDatabase;
- [Supplemental, NoInterfaceObject]
- interface WorkerUtilsDatabase {
- 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);};
- WorkerUtils implements WorkerUtilsDatabase;
- [Callback=FunctionOnly, NoInterfaceObject]
- interface DatabaseCallback {
- void handleEvent(in Database database);
- };
2,SQLTransaction接口,关注executeSql方法
- typedef sequence<any> ObjectArray;
- interface SQLTransaction {
- void executeSql(in DOMString sqlStatement, in optional ObjectArray arguments, in optional SQLStatementCallback callback, in optional SQLStatementErrorCallback errorCallback);};
- [Callback=FunctionOnly, NoInterfaceObject]
- interface SQLStatementCallback {
- void handleEvent(in SQLTransaction transaction, in SQLResultSet resultSet);};
- [Callback=FunctionOnly, NoInterfaceObject]
- interface SQLStatementErrorCallback {
- boolean handleEvent(in SQLTransaction transaction, in SQLError error);
- };
3,最后看下SQLResultSetRowList定义
- interface SQLResultSetRowList {
- readonly attribute unsigned long length;
- getter any item(in unsigned long index);
- };
和SQLResultSet定义
- interface SQLResultSet {
- readonly attribute long insertId;
- readonly attribute long rowsAffected;
- readonly attribute SQLResultSetRowList rows;
- };
(转)HTML 5离线存储之Web SQL的更多相关文章
- (转)HTML5开发学习(3):本地存储之Web Sql Database
原文:http://www.cnblogs.com/xumingxiang/archive/2012/03/25/2416386.html HTML5开发学习(3):本地存储之Web Sql Data ...
- 前端存储之Web Sql Database
前言 在上一篇前端存储之indexedDB中说到,我们项目组要搞一个前后端分离的项目,要求在前端实现存储,我们首先找到了indexedDB,而我们研究了一段时间的indexedDB后,发现它并不是很适 ...
- localForage——轻松实现 Web 离线存储
Web 应用程序有离线功能,如保存大量数据集和二进制文件.你甚至可以做缓存 MP3 文件这样的事情.浏览器技术可以保存离线数据和大量的储存.但问题是,如何选择合适技术,如何方便灵活的实现. 如果你需要 ...
- HTML5 Web 客户端五种离线存储方式汇总
最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利用了Cookie.WebStorage.IndexedDB以及Fi ...
- Web离线存储的几种方式
随着HTML5的正式定稿,我们也可以大量使用HTML离线网络应用程序的特性. #1.Application Cache Application Cache 可以很简单让我们的WebApp具有离线的能力 ...
- Atitit.h5 web webview性能提升解决方案-----fileStrore缓存离线存储+http方案
Atitit.h5 web webview性能提升解决方案-----fileStrore缓存离线存储+http方案 1. 业务场景 android+webview h5 css背景图性能提升1 2. ...
- HTML5本地存储——Web SQL Database
在HTML5 WebStorage介绍了html5本地存储的Local Storage和Session Storage,这两个是以键值对存储的解决方案,存储少量数据结构很有用,但是对于大量结构化数据就 ...
- HTML5 学习笔记(三)——本地存储(LocalStorage、SessionStorage、Web SQL Database)
一.HTML4客户端存储 B/S架构的应用大量的信息存储在服务器端,客户端通过请求响应的方式从服务器获得数据,这样集中存储也会给服务器带来相应的压力,有些数据可以直接存储在客户端,传统的Web技术中会 ...
- web sql database数据存储位置
Q1: 数据存储在哪儿? Web Storage / Web SQL Database / Indexed Database 的数据都存储在浏览器对应的用户配置文件目录(user profile di ...
随机推荐
- MySQL初级培训
按照一个MySQL DBA在工作中接触到部分的先后顺序,编排培训目录如下. 字段选取 int , decimal, char , varchar , blob ,timestamp SQL优化 exp ...
- robotframework笔记19
后处理输出 使用时自动测试 在测试执行报告和日志生成,并使用它 分别允许创建自定义报告和日志以及结合 和合并的结果. 使用Rebot 简介 rebot [options] robot_outputs ...
- oracle错误码
ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 ORA-00020: 超出 ...
- MASM6.15汇编程序例子
/***************通过调用(INT 21H)表中的01h号功能号从键盘输入一个字符并回显到视频显示器上*****************/ DATAS SEGMENT ;此处输入数据段代 ...
- backbonejs中的模型篇(一)
一:模型及属性 模型是MVC应用的基石,它负责存放应用所需的数据,对数据的验证,执行访问控制,以及实现应用所需的特定业务逻辑. backbone通过扩展Backbone.Model对象来定义一个模型. ...
- 怎么设置 mysql 多主复制
更新 其实本文主要来自www.digitalocean.com ,但是我没有买他们家的 VPS 用来 demo 了.只是用vagrant 来模拟了. 介绍 说说关于通过两台 vps 来扩展 mysql ...
- Apache网页有时能访问,有时超时打不开
在win server 2008上安装wamp2.4版本,配置apache 访问网页一直在加载,似乎被挂起. 转圈需要3分钟多钟, 最终显示无法访问. 或者超时. 错误日志中有如下提示: [Sat J ...
- SqlServer2008快照隔离模式的业务应用
场景: 有200个检测点,每个检测点每天采集5个数据,对表的读写都是随机的(即有可能同时读写),总共有5年的数据. 存储方案A: 日期 点号 类型 值 20120101 001 A 1.0 20120 ...
- [Js]缓冲运动
一.运动框架 1.在开始运动时,关闭已有定时器(否则会不断有新的定时器执行) 2.把运动和停止隔开(if/else) 二.缓冲运动 逐渐变慢,最后停止(距离越远速度越大) 速度=(目标值-当前值)/缩 ...
- http://www.html-js.com/article/2328
React.js编程思想 张小俊128 发布在使用React.js开发web应用2015年8月7日view:33385React 在文章任何区域双击击即可给文章添加[评注]!浮到评注点上可以查看详情. ...