最近我们的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 }
就这么多吧,想起来了,再补充