javascript 本地数据库存储websql

  最近我们的APP不太行了,因为是一个有做题,提交题目的功能,之前只是从APP提交错题到服务端,服务端难道答案,校验答案的对错,返回结果集,现在很多用户反映,提交速度很慢,很多时候,都提交不成功,所以领导让我把题目存在本地,校验题目的任务也交给前端来实现,服务端只接受并存储错误的题目,从而减轻服务端的压力,

  在因为我们的题库量是很大的,而且种类比较多,每年两套题,一套题有100道左右的题目,所以单纯的localstorage并不能满足我们,因此我们选择了使用数据库,最开始,想试试sqllit,但是本身H5的标准里没有推荐,下面这个链接,可以看到dcloud提供的APP离线存储方案,可以选择

                     http://ask.dcloud.net.cn/article/166

  最终我们使用的websql,再使用websql的时候,遇到了几个坑

  1.数据库操作是异步的,有的时候很烦,例如我要获取一百道题目之后,对这些题目操作,返回值得方法,我没怎么用我使用的是回调函数传参的方法,感觉用起来一般,有的时候,太复杂的操作,经常会出问题,因为毕竟是函数,闭包你懂得。

  2.数据库版本号的修改,这个情况确实恶心,我本来以为很简单就可以解决的小垃圾,卡了老子半个下午,最终配合localstorage才解决,神烦的一个机制

  简单介绍一下:

  数据库再每次打开的时候,都需要有一个版本号,如果在打开数据库的时候,传入的版本号,和数据本身的版本号不同,那么就会报错,而且报的错贼奇葩

      

  这是当我吧2.0版本的数据库,修改版本为1.0的时候报的错,解决方法:每次打开生成数据库的时候,都从localstorage里面取,当获取到的数据库版本号和本地不同的时候,我们需要,先打开一下数据库,获取到dataBase对象,然后,修改数据库版本,dataBase身上有原生的changeVersion方法,用来修改数据库的版本,然后同步到localstorage,下次数据库再打开的时候,直接从localstorage里面拿最新的;( ^ - ^ )

  3.在插入数据的时候,不要跳转页面,由于是异步插入的,所以很容易出现插入到一把,跳页面了,结果就是,终止了循环,不插了,所以如果出现了跳转页面和插入数据在同一个函数里面的收,尽量放到跳转之后的页面里面去插入

  下面贴上我在操作的时候,封装的Js文件( 其实我也是网上找的,自己根据需求修改了一下 )

  websql.js

  1 /**
  2 *数据库操作辅助类,定义对象、数据操作方法都在这里定义
  3 */
  4 var dbname='yearstopic';/*数据库名*/
  5 var dbdesc = '历年真题题库'; /*数据库描述*/
  6 var dbsize = 20*1024*1024; /*数据库大小*/
  7 var dataBase = null; /*暂存数据库对象*/
  8 /*数据库中的表单名*/
  9 var websqlTable = "websqlTable";
 10 /**
 11  * 打开数据库
 12  * @returns  dataBase:打开成功   null:打开失败
 13  */
 14 function websqlOpenDB(){
 15     /*数据库有就打开 没有就创建*/
 16    var version = window.localStorage.DBversion;
 17     dataBase = window.openDatabase(dbname, version, dbdesc, dbsize);
 18     if (dataBase) {
 19         console.log("数据库创建/打开成功!");
 20     } else{
 21         console.log("数据库创建/打开失败!");
 22     }
 23     return dataBase;
 24 }
 25 //修改数据库版本
 26 function changeDataBaseVersion(old_version,new_version){
 27     var db  = websqlOpenDB();
 28     db.changeVersion(old_version,new_version,null,function(err){},null)
 29     window.localStorage.DBversion = new_version;
 30 }
 31 /**
 32  * 新建数据库里面的表单
 33  * @param tableName:表单名
 34  */
 35 function websqlCreatTable(tableName){
 36 //  chinaAreaOpenDB();
 37     var creatTableSQL = 'CREATE TABLE IF  NOT EXISTS '+ tableName+'(ID text,QUESTION text)';
 38     dataBase.transaction(function (ctx,result) {
 39         ctx.executeSql(creatTableSQL,[],function(ctx,result){
 40             console.log("表创建成功 " + tableName);
 41         },function(tx, error){
 42             console.log('创建表失败:' + tableName + error.message);
 43         });
 44     });
 45 }
 46 //插入数据
 47 function websqlInsterDataToTable(tableName,id,question){
 48     var question = JSON.stringify(question);
 49     var insterTableSQL = 'INSERT INTO ' + tableName + ' VALUES (?,?)';
 50     dataBase.transaction(function (ctx) {
 51         ctx.executeSql(insterTableSQL,[id,question],function (ctx,result){
 52             console.log("插入" + tableName + id + "成功");
 53         },
 54         function (tx, error) {
 55             console.log('插入失败: ' + error.message);
 56         });
 57     });
 58 }
 59 /**
 60  * 获取数据库一个表单里面的所有数据
 61  * @param tableName:表单名
 62  * 返回数据集合
 63  */
 64 function websqlGetAllData(tableName,fn){
 65     var selectALLSQL = 'SELECT * FROM ' + tableName;
 66     dataBase.transaction(function (ctx) {
 67         ctx.executeSql(selectALLSQL,[],function (ctx,result){
 68             console.log('查询成功: ' + tableName +'__'+ result.rows.length);
 69             var len = result.rows.length;
 70             var queryDataArray = [];
 71             for(var i = 0;i < len;i++) {
 72                     queryDataArray.push(JSON.parse(result.rows.item(i).QUESTION));
 73             }
 74             fn(queryDataArray);
 75         },
 76         function (tx, error) {
 77             console.log('查询失败: ' + error.message);
 78         });
 79     });
 80 }
 81 //查询所有数据,获取json格式
 82 function websqlGetAllDataJson(tableName,fn){
 83     var selectALLSQL = 'SELECT * FROM ' + tableName;
 84     dataBase.transaction(function (ctx) {
 85         ctx.executeSql(selectALLSQL,[],function (ctx,result){
 86             console.log('查询成功: ' + tableName +'__'+ result.rows.length);
 87             var len = result.rows.length;
 88             var queryDataArray = {};
 89             for(var i = 0;i < len;i++) {
 90                 var id = result.rows.item(i).ID;
 91                 id = id.replace('.0','');
 92                 queryDataArray[id] = JSON.parse(result.rows.item(i).QUESTION);
 93             }
 94             fn(queryDataArray);
 95         },
 96         function (tx, error) {
 97             console.log('查询失败: ' + error.message);
 98         });
 99     });
100 }
101 /**
102  * 获取数据库一个表单里面的部分数据
103  * @param tableName:表单名
104  * @param name:姓名
105  */
106 function websqlGetAData(tableName,id,fn){
107     var selectSQL = 'SELECT * FROM ' + tableName + ' WHERE ID = ?'
108     dataBase.transaction(function (ctx) {
109         ctx.executeSql(selectSQL,[id+'.0'],function (ctx,result){
110             fn && fn(JSON.parse(result.rows.item(0).QUESTION))
111         },
112         function (tx, error) {
113             console.log('查询失败: ' + error.message);
114         });
115     });
116 }
117 
118 function webSqlDeleteTable(tabName){
119     dataBase.transaction(function(tx) {
120         tx.executeSql('DROP TABLE '+tabName+'');  
121         console.log('删除表'+tabName+'成功')
122     },
123     function(tx,err){
124         console.log('删除表'+tabName+'失败')
125     })
126 }
127 /**
128  * 删除表单里的全部数据
129  * @param tableName:表单名
130  */
131 function websqlDeleteAllDataFromTable(tableName){
132     var deleteTableSQL = 'DELETE FROM ' + tableName;
133     localStorage.removeItem(tableName);
134     dataBase.transaction(function (ctx,result) {
135         ctx.executeSql(deleteTableSQL,[],function(ctx,result){
136             console.log("删除表成功 " + tableName);
137         },function(tx, error){ 
138             console.log('删除表失败:' + tableName + error.message);
139         });
140     });
141 }

  就这么多吧,想起来了,再补充

   

posted @ 2017-08-25 10:48  击鼓卖糖  阅读(1332)  评论(0编辑  收藏  举报