0

0

HTML 5离线存储之Web SQL

php中文网

php中文网

发布时间:2016-05-17 09:09:40

|

1489人浏览过

|

来源于php中文网

原创

本篇没有考虑异步,多线程及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方法同质,均可返回记录集

诚石C2C交易系统
诚石C2C交易系统

1. 页面全部经过SEO(搜索引擎优化)处理 2. 支持IE、FireFox等主流浏览器,在IE 和FireFox下显示相同的效果 3. 符合W3C国际网页标准,页面全部采用DIV+CSS布局 4. 采用SQL server数据库,所有数据库操作采用存储过程 5. 部分功能采用AJAX技术,良好的用户体验。 6. 后台集成在线HTML编辑软件FCKEditor,自定义美观的内容

下载

整个 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 = "###\" title=\"delete\" onclick=\"javascript:_userStoryProvider.removeUserStory(\'" + id + "');removeRow(this);\">>>deletea>";
  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速学教程(入门课程)
HTML速学教程(入门课程)

HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

22

2026.01.27

拼多多赚钱的5种方法 拼多多赚钱的5种方法
拼多多赚钱的5种方法 拼多多赚钱的5种方法

在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

119

2026.01.26

edge浏览器怎样设置主页 edge浏览器自定义设置教程
edge浏览器怎样设置主页 edge浏览器自定义设置教程

在Edge浏览器中设置主页,请依次点击右上角“...”图标 > 设置 > 开始、主页和新建标签页。在“Microsoft Edge 启动时”选择“打开以下页面”,点击“添加新页面”并输入网址。若要使用主页按钮,需在“外观”设置中开启“显示主页按钮”并设定网址。

48

2026.01.26

苹果官方查询网站 苹果手机正品激活查询入口
苹果官方查询网站 苹果手机正品激活查询入口

苹果官方查询网站主要通过 checkcoverage.apple.com/cn/zh/ 进行,可用于查询序列号(SN)对应的保修状态、激活日期及技术支持服务。此外,查找丢失设备请使用 iCloud.com/find,购买信息与物流可访问 Apple (中国大陆) 订单状态页面。

184

2026.01.26

npd人格什么意思 npd人格有什么特征
npd人格什么意思 npd人格有什么特征

NPD(Narcissistic Personality Disorder)即自恋型人格障碍,是一种心理健康问题,特点是极度夸大自我重要性、需要过度赞美与关注,同时极度缺乏共情能力,背后常掩藏着低自尊和不安全感,影响人际关系、工作和生活,通常在青少年时期开始显现,需由专业人士诊断。

7

2026.01.26

windows安全中心怎么关闭 windows安全中心怎么执行操作
windows安全中心怎么关闭 windows安全中心怎么执行操作

关闭Windows安全中心(Windows Defender)可通过系统设置暂时关闭,或使用组策略/注册表永久关闭。最简单的方法是:进入设置 > 隐私和安全性 > Windows安全中心 > 病毒和威胁防护 > 管理设置,将实时保护等选项关闭。

7

2026.01.26

2026年春运抢票攻略大全 春运抢票攻略教你三招手【技巧】
2026年春运抢票攻略大全 春运抢票攻略教你三招手【技巧】

铁路12306提供起售时间查询、起售提醒、购票预填、候补购票及误购限时免费退票五项服务,并强调官方渠道唯一性与信息安全。

178

2026.01.26

个人所得税税率表2026 个人所得税率最新税率表
个人所得税税率表2026 个人所得税率最新税率表

以工资薪金所得为例,应纳税额 = 应纳税所得额 × 税率 - 速算扣除数。应纳税所得额 = 月度收入 - 5000 元 - 专项扣除 - 专项附加扣除 - 依法确定的其他扣除。假设某员工月工资 10000 元,专项扣除 1000 元,专项附加扣除 2000 元,当月应纳税所得额为 10000 - 5000 - 1000 - 2000 = 2000 元,对应税率为 3%,速算扣除数为 0,则当月应纳税额为 2000×3% = 60 元。

39

2026.01.26

oppo云服务官网登录入口 oppo云服务登录手机版
oppo云服务官网登录入口 oppo云服务登录手机版

oppo云服务https://cloud.oppo.com/可以在云端安全存储您的照片、视频、联系人、便签等重要数据。当您的手机数据意外丢失或者需要更换手机时,可以随时将这些存储在云端的数据快速恢复到手机中。

172

2026.01.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.3万人学习

Node.js 教程
Node.js 教程

共57课时 | 9.5万人学习

CSS3 教程
CSS3 教程

共18课时 | 4.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号