那么使用Web DataBase,W3C主推的离线数据库类型

作者: 综合体育  发布:2019-12-02

事前的稿子()里面描述了HTML5 离线数据存款和储蓄的Web SQL,三个依照SQLite 的离线数据库,可是W3C 的 WebDatabase 标准中说那份正经不再维护了,取代他的是IndexDB,二个NoSQL类型的数据库。

依赖HTML5的Web DataBase 能够令你在浏览器中开展多少悠久地存款和储蓄管理和有效性查询,假诺你的离线应用程序有供给标准化的寄放功用,那么使用Web DataBase,能够令你的应用程序无论是在离线恐怕在线可能网络不畅通境况下都得以将数据保存在客户端。

 图片 1

上面是HTML5 DataBase中多个不等的DataBase的比较,摘自 上边的生机勃勃篇作品。

Html5罗克s把她们的利弊做了比对,IndexDB综合看来犹如下优点:

图片 2

允许连忙索引和寻找的对象,所以在HTML5 的 web应用程序中, 你能够使得管理你的数码和高功能的读/写操作。

咱俩这边使用WebSQL来安排和编写制定底层服务,W3C 的 WebDatabase 标准中说那份正经不再维护了,可是差不离完结者都接受了SQLite这种轻量简单易用的客商端数据库:

W3C首选的离线数据库类型,慢慢代替Web SQL类型数据库,更新频率高并不断完备。

当今我们来封装和提取WebSQL公用方法。

职业在异步方式下举办每步操作。让您利用高效能的的JavaScript事件驱动模块

 

 

第一,我们需求获得SQLite数据库可操作和实践的SQL数据上下文:

明日我们来尝试接纳那么些IndexDB:

那边经过openDatatBase方法张开或创办数据库:

1、开首化申明

图片 3图片 4View Code

图片 5图片 6

 1 /*-------执行SQLite注入,数据库的基本操作(Begin)-------*/
 2 function SQLProvider(dbName, size) {
 3     this.dbName = dbName || 'OFLMAIL';
 4 
 5     var db = openDatabase(this.dbName, '1.0', 'database for '   this.dbName, (size || 2) * 1024 * 1024);
 6     this.db = db;
 7 
 8     /*-------执行SQLite注入,数据库的基本操作(End)-------*/
 9 
10     function sqlerrorHandler(tx, e) {
11         log.error(e.message);
12     }
1             var dbName = "H5AppDB"; //数据库名称
2             var dbVersion = 2.0; //数据库版本
3             var tablename = "todo"; //表名

那边还足以安装数据库的名称dbName和数据库大小size,暗中同意数据库名称是OFLMAIL,正是大家这么些离线系统的名号,私下认可大小是2兆。

View Code

小编们仍是可以够设置错误管理方法sqlErrorHandler,客户管理操作失利以往的荒诞捕捉

 

那般,我们就得到了操作SQLite的数码上下文db,通过上下文db,大家得以试行相应的CU安德拉D操作。

2、开头并实例化IndexDB数据上下文 

 

图片 7图片 8

先是步,大家写贰个创造数据表的不二秘技,把那些措施放在SQLProvider方法体里面, 

 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             };

图片 9图片 10View Code

View Code

 1     /*--添加数据表--*/
 2     this.createTable = function (tableName, fields, callBack) {
 3         var pkField = tableName   "_SEC";
 4         var sql = "CREATE TABLE IF NOT EXISTS "   tableName   "( "   pkField   " integer primary key autoincrement,";
 5 
 6         // 合并字段串同时去除传入的主键字段
 7         sql  = fields.join(",").replace(pkField   ",", "")   ")";
 8         //log.debug(sql);
 9 
10         db.transaction(function (tx) {
11             tx.executeSql(sql, [], function () {
12                 if (callBack) callBack();
13             }, sqlerrorHandler);
14         })
15     }

 

共计包罗了四个参数tableName,fileds,callBack,分表代表你要开创的表名,所对应的字段数组,正是把这几个表相应的字段用数组保存起来(方法里面还大概会自动成立二个表名加上“_SEC”的字段,他是个增量标志,用做主键卡塔尔(قطر‎,callBack看名就可以预知意思,回调函数,这么些参数能够不传。那几个回调函数的存在很要紧,因为任何基于SQLite数据库的操作方法都以异步调用的,所以要求在回调函数中嵌套试行,不然有个别试行会被中止。

3、展开数据库,早先化数据库,并成立存款和储蓄对象

 

图片 11图片 12

将这一个函数放在SQLProvider里面,有贰个收益正是届时候能够在SQLProvider的动态实例化中央机关单位接调用该函数

 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             };

如:var sqlProvider = new SQLProvider();

View Code

 sqlProvider.createTable(“UserInfo”,new Array(“UserName”,”UserPwd”)); 

 

这样子,方便大家在页面中调用。这种操作方法相当于C#内部的动态类创造方法,SQLProvider正是类名,createTable正是类中的方法,实例化调用。

4、获取对象新闻,并张开轮询读取,然后绑定到页面

 

图片 13图片 14

接下去大家的数据库的操作,富含数据表和数量的CU兰德路虎极光D操作,都会以这种办法写在其间:

 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     };

除去数据表(只需传入表名就可以了,他会去除相应的数据表):

View Code

图片 15图片 16View Code

 效果如下:

1     /*--删除数据表--*/
2     this.dropTable = function (tableName) {
3         var sql = "DROP TABLE "   tableName;
4         db.transaction(function (tx) {
5             tx.executeSql(sql);
6         })
7     }

图片 17

 

 

增进数码(包蕴了七个参数:表名,字段数组,字段所对应的值的数组,和二个回调函数)

5、增多数据对象

那边的田野(field卡塔尔s和values代表了字段数组和值数组,他们意气风发生龙活虎对应:

图片 18图片 19

如 var fileds=new Array(“UserName”,”UserPwd”);

 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             }

   var values=new Array(“Ben”,”123456”卡塔尔国;则注解在UserInfo表里面增加了一条数据,那条数据最少含有四个有值的字段,主键,UserName和UserPwd,而values 则是对应的值数组。

View Code

   回调函数中蕴藏二个回去的参数,重临了你所增进的改行数据的主键。

 能够自便增加BJson格式的靶子,展现NoSQl类型数据库的优质性...

图片 20图片 21View Code

图片 22

 1     /*--添加数据(插入数据)--*/
 2     this.insertRow = function (tableName, fields, values, callback) {
 3         var sql = "INSERT INTO "   tableName   " ("   fields.join(",")   ") SELECT "
 4            new Array(values.length   1).join(",?").substr(1);
 5 
 6         db.transaction(function (tx) {
 7             tx.executeSql(sql, values, function () { }, sqlerrorHandler);
 8             //log.debug(sql);
 9 
10             tx.executeSql("SELECT max("   tableName   "_SEC) id from "   tableName, [], function (tx, result) {
11                 var item = result.rows.item(0);
12                 var id = parseInt(item.id);
13                 //log.debug("id="   id);
14                 if (callback) callback(id);
15             }, sqlerrorHandler);
16         });
17     }

 

 

6、删除数据对象(依照主键删除)

除去数据 (满含了四个参数:表名tableName,主键sec和四个回调函数callback)

图片 23图片 24

以此主键SEC是该待删除的数量在Web DataBase中的主键,大家前边在建表的时候有二个增量标志字段,该字段的称号为表名加上“_SEC”,因为唯后生可畏性,所以大家得以依据那几个主键来删除该行数据,

 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       };

代码如下:

View Code

图片 25图片 26View Code

 

1     /*--删除数据--*/
2     this.deleteRow = function (tableName, sec,callback) {
3         var pkField = tableName   "_SEC";
4         var sql = "DELETE FROM "   tableName   " WHERE "   pkField   " = ?";
5         db.transaction(function (tx) {
6             tx.executeSql(sql, [sec], null, sqlerrorHandler);
7             if (callback) callback(); //使用回调 
8         })
9     }

W3C已经告朝气蓬勃段落了对Web SQL  的更新,会愈发康健对Index的正经八百草案和标准,所现在来的HTML5应用,有采纳离线端数据库这一块,建议优先思谋IndexDB...

 

 

校勘数据(那边包罗了三个参数,表名tableName,字段数组田野(field卡塔尔(قطر‎s,值数组values,回调函数callback)

正文源码

字段数组和值数组必得是各种对应的,何况首先个字段必需是主键,所对应的values的率先个值也一定要是主键的值,这样,能够依据字段的主键来查询相应的数据行。

摸清的数据行之后,能够依据前面包车型大巴相应字段,举办改动。

图片 27图片 28View Code

 1     /*--更新列,这边需要注意的是两个参数列表的首位必须是主键(或者说第一个必须是条件,后面的是修改位)--*/
 2     this.updateRow = function (tableName, fields, values,callback) {
 3         var len = fields.length;
 4 
 5         var sql = "";
 6         for (i = 1; i < len; i  ) {
 7             if (i == 1) sql  = fields[i]   " = '"   values[i]   "'";
 8             else sql  = ","   fields[i]   " = '"   values[i]   "'";
 9         }
10 
11         sql = 'UPDATE '   tableName   ' SET '   sql   ' where '   fields[0]   '= ?';
12         //log.debug("sql:"   sql);
13 
14         db.transaction(function (tx) {
15             tx.executeSql(sql, [values[0]],
16              null, sqlerrorHandler);
17             //log.debug("update "   tableName   " success! sec="   values[0]);
18             if (callback) callback();
19         });
20     }
21 }

调用方式临近如下:

var fileds=new Array(“UserInfo_SEC”,“UserName”,”UserPwd”);

var values=new Array(“5”,“Ben”,”123456”);

sqlProvider.updateRow(“UserInfo”,fileds ,values,function(){

  log.debug(“修改成功!”卡塔尔(英语:State of Qatar);

});

那样子正是在UserInfo表里面改良主键为5的数额行,校订它的UserName的值为:“Ben”,

校正它的UserPwd的值为:“123456”

 

据他们说主键查询单行数据(富含四个参数表名tableName,主键SEC,回调函数callback):

依附表名和主键名称获取到该行数据,并重临,注意到那边经过cllback回调函数来回到查询的结果,通过数量上下文tx实施该SQL脚本,重回的是结果集result,那边大家取他结果集的率先条数据也便是result.rows.item(0卡塔尔(قطر‎,实际上结果集中也唯有一条数据。

图片 29图片 30View Code

1     /*--读取单行数据--*/
2     this.readRow = function (tableName, sec, callback) {
3         db.transaction(function (tx) {
4             tx.executeSql('SELECT * FROM '   tableName   ' WHERE '   tableName   '_SEC = ?', [sec], function (tx, result) {
5                 if (callback) callback(result.rows.item(0)); // 使用回调  
6             }, sqlerrorHandler);
7         });
8     }

 

读取钦定的数据表(依照表名来读取相应的数据表,并赶回结果集):

图片 31图片 32View Code

1     /*--读取数据表--*/
2     this.loadTable = function (tableName, callback) {
3         db.transaction(function (tx) {
4             tx.executeSql('SELECT * from '   tableName, [], function (tx, result) {
5                 if (callback) callback(result); //使用回调                
6             }, sqlerrorHandler);
7         });
8     }

结果集result中的列的群集用result.rows表示

列的多寡用result.rows.length来表示

单条数据是用result.rows.item(index卡塔尔表示,index指的是列的目录地点,从0开首

 

依附SQL的where条件语句来读取钦命的数据表(依照表名tableName和sqlSenten条件语句来实践,并赶回结果集):

图片 33图片 34View Code

1     /*--根据查询条件读取数据表--*/
2     this.loadTableBySQl = function (tableName, sqlSenten, callback) {
3         db.transaction(function (tx) {
4             tx.executeSql('SELECT * from '   tableName " WHERE "  sqlSenten, [], function (tx, result) {
5                 if (callback) callback(result); //使用回调                
6             }, sqlerrorHandler);
7         });       
8     }

与地方的法门类似,只是多了一个sqlSenten条件语句来筛选数据

 

故事某些字段检查是还是不是存在该列(通过字段名和字段所对应的值)来展开操作,过多地用于遵执照主人键来询问数据行:

图片 35图片 36View Code

 1     /*--检查是否已存在该列--*/
 2     this.checkExist = function (tableName, fieldName, fieldValue, callback) {
 3         db.transaction(function (tx) {
 4             tx.executeSql('SELECT * from '   tableName   ' where '   fieldName   '= ?', [fieldValue], function (tx, result) {
 5                 var isExist;
 6                 if (result.rows.length == 1) isExist = "1"; else isExist = "0"; //1代表存在该行,0 代表不存在该行
 7                 if (callback) callback(isExist);
 8             }, sqlerrorHandler);
 9         });
10     }

当检索读到的结果集结中带有了一条数据的时候,重回1,代表存在该行,为0的时候表示不设有该行。那边做的实际上不到家只好在唯意气风发值的字段中工夫够过不错呈现,如主键,别的还足以经过where条件语句来验证是不是存在该行。那边就背着了,自身去尝尝。

这么就到位了上上下下离线数据库的CUXC60D操作,借使有相当不足的地点,大家得以持续改善康健,完整代码如下,在代码的末尾大家开展了实例化,大家把这个代码独立地寄放到WebDataBase.js文件之中,这样能够在三番五次这么些本子文件的页面里直接调用那几个脚本库的诀窍。

 

到现在大家把那几个数据库的的操作使用到大家的系统中,

大家的客商音信页面(Information.html),用来保存登入顾客的个人音信的:

带有了之类字段:姓名,性别,入职时间,工号和单位:

图片 37

 

在载入的时候查看是不是有多少,有数据则展现第一条

图片 38图片 39View Code

 1  $(document).ready(function () {
 2             sqlProvider.loadTable("UserInfo", function (result) {
 3                 // result.rows 获取到所有数据行
 4                 if (result.rows.length > 0) {
 5                     var row = result.rows.item(0);
 6                     $("#UserName").val(row.UserName);
 7                     $("#UserSex").val(row.UserSex);
 8                     $("#ReportDutyTime").val(row.ReportDutyTime);
 9                     $("#JobNumber").val(row.JobNumber);
10                     $("#DepartmentNumber").val(row.DepartmentNumber);
11                   //这边包含一个隐藏域,可以保存该用户信息的主键  
12                   $("#UserInfo_SEC").val(row.UserInfo_SEC);
13                 }
14             })
15         })

大家的保留开关的代码如下:

图片 40图片 41View Code

 1     function onformsumit() 
 2     {
 3     //创建用户信息表(存在跳过,不存在创建),包含六个字段,
 4     //因为创建的时候会自动创建一个UserInfo_SEC的主键,所以实际上是6个字段
 5     //UserName:用户名称
 6     //UserSex:用户性别
 7     //ReportDutyTime:入职时间
 8     //JobNumber:工号
 9     //DepartmentNumber:部门
10     //Remark:备注
11     
12     
13             var UserName = $("#UserName").val();
14             var UserSex = $("#UserSex").val();
15             var ReportDutyTime = $("#ReportDutyTime").val();
16             var JobNumber = $("#JobNumber").val();
17             var DepartmentNumber = $("#DepartmentNumber").val();
18             var Remark = "";
19 
20             var fields = new Array("UserName", "UserSex", "ReportDutyTime", "JobNumber", "DepartmentNumber", "Remark");
21             var values = new Array(UserName,UserSex,ReportDutyTime,JobNumber,DepartmentNumber,Remark);
22             sqlProvider.createTable("UserInfo", fields, function () {
23                 log.debug("创建数据表UserInfo");
24 
25                 var UserInfo_SEC = $("#UserInfo_SEC").val();
26                 //取隐藏域的值,如果是0则为保存不为0则为修改
27                 if (UserInfo_SEC == "0") {
28                     sqlProvider.insertRow("UserInfo", fields, values, function () {
29                         log.debug("插入数据成功!");
30                         alert("保存成功!");
31                     });
32                 }
33                 else {
34                     sqlProvider.updateRow("UserInfo", fields, values, function () {
35                         log.debug("修改数据成功!");
36                         alert("保存成功!");
37                     });
38                 }
39             });
40           return false;
41       }

保留成功以往,数据就存款和储蓄在我们离线的数据Curry面了,载入时显得在页面效果如下:

图片 42

 

我们去浏览器中的DataBase中查阅,就能够看来这条数据了,如图:

图片 43

     //以下是表单重新初始化函数,删掉该客商音讯的代码

      function resets() { 

          var UserInfo_SEC = $("#UserInfo_SEC").val();

          if (UserInfo_SEC != "0") {

              sqlProvider.deleteRow("UserInfo", UserInfo_SEC, function () {

                  window.location.reload(true);

              })

          }

      }

 

2009.11.18, W3C 公布 将不再关心Web SQL databas,並且不再维护它的过时的正经,浏览器厂家也不会再在他们的新版浏览器中更新和晋级换代这一块,代替他的便是IndexedDB,W3C组织鼓劲和珍视使用IndexedDB。所以,提出学习职员去看一下IndexedDB的利用方法。

这是唇齿相依资料: 

正文的源码:CRX_Mail_WebDataBase

本文由新浦京3730发布于综合体育,转载请注明出处:那么使用Web DataBase,W3C主推的离线数据库类型

关键词: www.3730.com HTML5 项目笔记 Web HTML5