最近做一个webapp,需要将webview的数据存储到本地数据库,鉴于Android和webview传递大量数据比较麻烦,所以干脆直接存储在webview内置的本地数据库算了。
LocalStore
没有时间限制的本地存储,是上面三种存储方式中浏览器默认存储的容量最小的,也是最容易使用的,直接一句话完成存储过程。
存储数据:

localStorage.XXX=YYY

XXX可以随便命名,YYY是要存储的数据,可以是任何数据类型。
例如:

localStorage.status=true

localstore适合做少量数据的存储,一般用来存储网站某个变量的状态之类的

清除数据,有两种方式:
1) 删除一条数据

localStorage.removeItem(“key”);

Key对应上面的XXX
2)批量删除数据

localStorage.clear();

在浏览器可以看到其存储的数据,例如Google Chrome:
按F12查看开发者工具,然后点击上面的Application

重点来了,localStore在webview怎么用不了!!
原因是webView默认没有启动localStore功能的服务,需要我们自己手动去开启服务:

WebSettings settings = webview.getSettings();
settings.setDomStorageEnabled(true);

localStore用法比较简单,就介绍到这里,下面讨论一下websql的使用:

Websql
是当前最多浏览器支持的本地数据库,可以说目前主流的浏览器都支持了,手机的WebView 也不例外(WebView使用Websql也需要开启服务,这点我们下面再说)。
Websql是一个轻量级的本地数据库,存储量达到几百万条数据以上,使用起来也是相当简单的,支持原生的sql语句(SELECT、INSERT、DELETE、UPDATE),下面简单介绍用法:

1)、打开websql数据库用函数openDatabase();

db = openDatabase(“数据库名”, "版本号", "数据库的描述信息", 数据库的大小);

一个完整的例子:

var db = null;
try {if (window.openDatabase) {db = openDatabase(“myDB”, "1.0", "Database example", 10*1024*1024);
} catch(err) {db = null;alert("打开数据库失败");
}

2)、创建表(注意,一切对表的操作都要使用事务),并且使用executeSql 函数

//executeSql函数有四个参数(第一个参数必填,后三个可以不写),函数原型如下:
void executeSql(in DOMString sqlStatement, in optional ObjectArray arguments, in optional SQLStatementCallback callback, in optional SQLStatementErrorCallback errorCallback);

参数意义分别:
sqlStatement:是原生的sql语句。

例如:CREATE TABLE test (id, name)

ObjectArray:上一句sql语句中的占位符“?”所对应的参数,空则写“[]”

例如:select name from student where id=?,[001]

callback:本次sql操作成功后的回调接口,数据会被返回
errorCallback:本次sql操作失败后的回调接口,失败信息会被返回

创建一张test表:

db.transaction(function(tx) {tx.executeSql('CREATE TABLE test (id, name)');
});

3)、插入(INSERT)操作

db.transaction(function (tx){tx.executeSql("INSERT INTO test (id, name) VALUES ( ?, ?)", [001, “Biao”]);
});

4)、查询(SELECT)操作

db.transaction(function(tx) {tx.executeSql("SELECT * FROM test ", [], function(tx, result) {// result就是查询到的结果}, function(tx, error) {alert('查询失败 ' + error.message);return;});
});

5)、更新(UPDATE)操作

db.transaction(function (tx){tx.executeSql("UPDATE test SET name = ? WHERE id = ?", [“wu”, 001]);
});

6)、删除(DELETE)操作

db.transaction(function(tx){tx.executeSql("DELETE FROM test WHERE id = ?", [001]);});

表创建成功之后同样也可以在web浏览器的开发者工具上看到数据(例如:谷歌浏览器)

以上就是Websql的四个主要操作了。

那么问题又来了,怎么Android Webview用不了Websql呢?

刚才已经说了,Websql是目前浏览器支持最为广泛的一个内置的本地数据库,没有之一,并且Android的Webview也已经支持了,但是,Webview默认是没有开启这个服务的,还是得我们自己开启,操作步骤如下:

WebSettings settings = webview.getSettings();
//设置与Js交互的权限
settings.setJavaScriptEnabled(true);
//设置数据库可用
settings.setDatabaseEnabled(true);
String dbPath = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
settings.setDatabasePath(dbPath);//然后
webview.setWebChromeClient(new MyChromeViewClient());class MyChromeViewClient extends WebChromeClient {//重写这个方法就OK 了
@Override
public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater){//设置数据库存储大小quotaUpdater.updateQuota(estimatedSize * 2);}
}

现在就可以在Webview上使用websql了

websql对数据的操作尽然不比localStore存储方便,但是这两个是没法比的,Websql存储数据是以一张张表的形式存在,存储量比localStore大多了。而且它对数据的操作还是我们相当熟悉的SQL语句。总而言之,方便好用。

但是!!大家有没有发现,我们再看看对数据的操作,全部得手写原生SQL语句!!SELECT INSERT UPDATE DELETE,当数据表的字段非常多的时候,所有字段都得我们自己去写入。不知道大家会不会觉得烦,反正我是烦了。

幸亏有IndexDB
indexDB 支持本地存储大量对象,并使用健壮的数据访问机制检索数据。插入数据支持直接使用JSON数据,关键的是它不需要我们手写原生SQL语句来对数据进行查增删改。

下面简单介绍其用法
创建或者打开数据库

window.indexedDB.open(dbName, 1);

参数意义:
dbName:数据库的名称
1:版本号

1)、创建表

db.createObjectStore(tbName,{"keyPath":"keyID", autoIncrement:true});  

参数意义:
tbName:表名称
{“keyPath”:”keyID”, autoIncrement:true}:设置字段keyid为主键,并且设置自动自增属性
可以添加字段,例如,添加name 字段
objectStore.createIndex(“name”, “name”,{unique:false});
参数意义:
“name”:字段名
“name”:设置字段name为索引,设置为索引后在查询的时候可以以name字段进行查询,加快查询速度。
{unique:false}:设置属性:不唯一。换句话说就是可以存在相同名字的数据

2)、插入数据(INSERT):

INDEXDB 和 WebSQL一样,对数据处理的时候要使用到事务

//获取事务
var transaction = database.transaction([tableName], model);
//参数意义:
//tableName:要操作的表名
//model:模式,有两种,readwrite(可读可写) 和readonly(只读)//获取表
var objectStore = transaction.objectStore(tableName);var request = objectStore.put(date);
request.onerror = function(event) {alert("发生错误:" + request.error);
};
request.onsuccess = function(event) {alert("数据保存成功");
};

大家可以看到,上面没有出现字段名就完成对数据的插入了,上面的date是一个JS对象,只要把数据转换为JS对象数据就可以利用函数objectStore.put(date);插入数据了,其实也可以利用函数objectStore.add(date);插入数据。
如果是JSON 数据 可以利用$.parseJSON(data)来将JSON数据转成JS对象,然后对数据进行插入操作

put和add方法的区别在于,put插入数据的话

如果主键存在表中,那么就把旧数据更新
如果主键不存在表中,就插入一条新的数据。

add插入数据的话

如果主键存在表中,那么就会报错
如果主键不存在表中,就插入一条新的数据。

3)、查询数据(SELECT):

3.1)获取一条数据用函数get(key);

var transaction = database.transaction([tableName], model);
var objectStore = transaction.objectStore(tableName);
//key是主键的某一个值
var request = objectStore.get(key);
request.onerror=function(e){alert("发生错误:" + request.error);
};
request.onsuccess=function(e){var result=e.target.result;console.log("获取数据成功");
}

3.2)获取所有数据用函数getAll();

var transaction = database.transaction([tableName], model);
var objectStore = transaction.objectStore(tableName);
var request = objectStore.getAll();
request.onerror=function(e){alert("发生错误:" + request.error);
};
request.onsuccess=function(e){var result=e.target.result;console.log("获取数据成功");
}

但是getAll()函数不推荐使用,貌似已经废弃了,反正我在平板Android4.4.2的webview上面不能使用

3.3)推荐使用openCursor()利用游标的方式来进行查询多条数据,功能非常强大, 可以利用索引加快查询速度,还可以指定搜索的范围。

var transaction = database.transaction([tableName], model);
var objectStore = transaction.objectStore(tableName);
objectStore.openCursor().onsuccess = function(event) {  var cursor = event.target.result;  if (cursor) {  var rowData = cursor.value;  for (var Key in rowData){console.log("查询的数据"+Key[0]);          }cursor.continue();  console.log(“1”);  }else{console.log(“2”);  }
}  

cursor.continue(); 表示,查询到了继续向前走,直至查询到所有结果截止。
注意,它和JAVA里面for循环的continue不一样,java的continue不会执行continue以后的语句,但是,cursor.continue();还是会执行以后的代码,例如上面的console.log(“1”);会一直被执行到。

但是!!

console.log(“2”);只会被执行一次,因为当cursor为空的时候,代表语句查询到所有结果了。

3.4)利用索引加快查询速度index(‘name’) name字段必须在一开始添加字段的时候给它设置为索引,如下:

objectStore.createIndex(“name”, “name”,{unique:false});

var transaction = database.transaction([tableName], model);
var objectStore = transaction.objectStore(tableName);
objectStore.index(‘name’).openCursor().onsuccess = function(event) {  var cursor = event.target.result;  if (cursor) {  var rowData = cursor.value;  for (var Key in rowData){console.log("查询的数据"+Key[0]);          }cursor.continue();  console.log(“1”);  }else{console.log(“2”);  }
}

3.5) 指定搜索的范围
使用到IDBKeyRange属性

Range           Code
//例如我上面指定主键是id , 意思就是查询id<=X的数据
//All keys ≤ x  IDBKeyRange.upperBound(x)
//查询id<X的数据
//All keys < x  IDBKeyRange.upperBound(x, true)
//查询id>=y的数据
//All keys ≥ y  IDBKeyRange.lowerBound(y)
//查询id>y的数据
//All keys > y  IDBKeyRange.lowerBound(y, true)
//All keys ≥ x && ≤ y   IDBKeyRange.bound(x, y)
//All keys > x &&< y    IDBKeyRange.bound(x, y, true, true)
//All keys > x && ≤ y   IDBKeyRange.bound(x, y, true, false)
//All keys ≥ x &&< y    IDBKeyRange.bound(x, y, false, true)
//查询id==z的数据
//The key = z   IDBKeyRange.only(z)
//查询id<=X的数据
var transaction = database.transaction([tableName], model);
var objectStore = transaction.objectStore(tableName);
objectStore.openCursor(IDBKeyRange.upperBound(x)).onsuccess = function(event) {  var cursor = event.target.result;  if (cursor) {  var rowData = cursor.value;  for (var Key in rowData){console.log("查询的数据"+Key[0]);          }cursor.continue();  console.log(“1”);  }else{console.log(“2”);  }
}

3.6)删除数据《2017.7.10 更新》
删除数据,indexDB的操作很简单

/** * 删除数据  * */
function deleteData(tbName,value){var objectStore = initDB(tbName,"readwrite");var request=objectStore.delete(IDBKeyRange.only(parseInt(value)));request.onerror=function(e){alert("发生错误:" + request.error);};request.onsuccess=function(e){var result=e.target.result;alert("删除数据成功");}
}

注意:用delete()方法,传值一定得是创建表的index索引,否则删除失败,例如

objectStore = db.createObjectStore(personDoc,{"keyPath":"keyID", autoIncrement:true});  

上面的代码是指在创建表中指定索引为keyID ,是一个自增值,整型,因此index索引是一个数值,IDBKeyRange.only(parseInt(value))这个就表示只删除索引值为value值的数据。

以上简单介绍了IndexDB的部分用法,总体来说,indexDB的学习成本不高,但其实用性和方便性很强。需要深入学习的朋友可以去MDN(链接)学习。

怎么在Android 的 webview上使用,可以参考websql的设置,他们两个是一样的,当然在浏览器上面也是可以看到indexDB数据库存储的数据的。例如:谷歌浏览器

最后贴上一份indexDB 的样例代码

$(function(){//全局数据库对象var database;//数据库的名称var dbName='HealDoc';//数据表var tbName='disease';//表字段var field="idcard/id/visitDate/visitWay/curSymptom/pressureH/pressureL/avoirdupois/bmi/arteriopalmus/smokeNum/drinkNum/trainingRate/trainingTime/rice/mentality/compiance/lastFbg/hgbde/hgbdedate/subCheck/dependence/sideEffects/effectsState/lowEffects/visitType/drugname/drugperday/drugpertime/drugname2/drugperday2/drugpertime2/drugname3/drugperday3/drugpertime3/insulin/insulinperday/insulinpertime/referralreason/referralagencies/nextDate/inputIdcard";//创建数据库var request = window.indexedDB.open(dbName, 1);request.onsuccess = function(event) {//让数据库 可在任何地方访问database = request.result;};request.onerror = function (event) {alert("发生错误:" + request.error);};request.onupgradeneeded = function(event) {alert("第一次创建数据库或者更新数据库。");db = request.result;  //创建表 var objectStore = db.createObjectStore(tbName,{"keyPath":"keyID", autoIncrement:true});  var fields=new Array();fields=field.split("/");for (var i = 0; i < fields.length; i++) {objectStore.createIndex(fields[i],fields[i],{unique:false});}}//对数据库处理得先初始化数据库//参数一:表名//参数二:操作数据库的模式 有两种:readwrite 和readonlyfunction initDB(tableName,model){//获取事务var transaction = database.transaction([tableName], model);//获取表var objectStore = transaction.objectStore(tableName);return objectStore;}function insert(date){var objectStore=initDB("disease","readwrite");//add 或者putvar request = objectStore.put(date);request.onerror = function(event) {alert("发生错误:" + request.error);};request.onsuccess = function(event) {alert("数据保存成功");};}function selectSingle(key){var objectStore=initDB("disease","readonly");var request=objectStore.get(key);request.onerror=function(e){alert("发生错误:" + request.error);};request.onsuccess=function(e){var result=e.target.result;console.log(result);}}function selectAll(){var objectStore = initDB("disease","readonly");var response="";// 打开游标,遍历customers中所有数据  objectStore.openCursor().onsuccess = function(event) {  var cursor = event.target.result;  if (cursor) {  var rowData = cursor.value;  for (var Key in rowData){response =response+Key+":"+rowData[Key]+"\n";}response+="\n\n\n"cursor.continue();  }  $('#output').val(response);}  }$('#submitButton').click(function(){var date = {};var t = $('#yourformid').serializeArray();// var str="";$.each(t, function() {date[this.name] = this.value;// str+=this.name+"/"});insert(date);return false;});$('#close').click(function(){selectAll();});
});

最后的最后,小弟不才,只能简述到这里了,如果有错误,请不吝赐教,如果有帮助到您的话,请留下一个start,O(∩_∩)O谢谢!

浅谈WebView利用localStore websql和IndexDB 来存储数据相关推荐

  1. 从春节12响浅谈漏洞利用

    春节12响是2019大年初一上映的电影<流浪地球>中的一个桥段,天才少年李11通过黑客技术,获得行星发动机控制权,从而拯救地球的故事. 本文简介了unix操作系统内核定时器事件.epoll ...

  2. vb怎么样实时取mysql数据库数据_浅谈如何使用vb.net从数据库中提取数据

    1.设置从Model中的Sub Main 启动 2.程序结构 3.Model1 Imports System.Windows.Forms.Application Module Module1 Sub ...

  3. 浅谈如何利用PERFORM打造高绩效团队

    有些团队无论面临多大困难的目标,都能有杰出的表现,圆满地完成任务,比如赢得冠军的体育团队,研究上取得惊人突破的科学团队,提出并实现独特创新想法的产品研发团队.这些高绩效团队横跨各行各业,而且规模.复杂 ...

  4. 转 Android开发学习笔记:浅谈WebView

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://liangruijun.blog.51cto.com/3061169/647456 ...

  5. 浅谈WebView的使用

    WebView是Android中一个非常实用的组件,它和Safai.Chrome一样都是基于Webkit网页渲染引擎,可以通过加载HTML数据的方式便捷地展现软件的界面.使用WebView开发软件有一 ...

  6. 浅谈USART_RX_STA各位的描述以及是如何实现数据接收的

    ①首先我们来看一下MDK对各位的描述 可以发现0~13位接受的是数据个数(填满相当于十进制的8191), ②那么既然0~13位数据量这么大,代码是如何实现对14.15位的修改呢?废话不多说,先上实现代 ...

  7. 浅谈:B2B电商平台驱动战略,数据+流量

    在流量思维鼓动下,每个企业都想一上来就收割流量,各种汽车项目一哄而上,为了获取流量,不惜花重金进行市场投放以求得快速笼络用户,但方方面面得不到一个系统性的解决方案,在增量用户转化上,那些靠补贴获取的用 ...

  8. koa html中添加数据,浅谈在koa2中实现页面渲染的全局数据

    最近用koa2做一个项目的web端,遇到一个场景. 该项目主要用的是传统的服务端渲染的方式,所以会用 koa-views 去做页面的渲染工作.实现方式就是 ctx.render('path',data ...

  9. rsync命令_浅谈利用rsync服务的攻击

    本文将根据针对Linux操作系统上不安全的Rsync配置,浅谈如何利用rsync服务进行攻击. 1.什么是RSYNC? Rsync是用于在两个服务器(通常是Linux)之间传输和同步文件的实用程序.它 ...

  10. 老杨说运维 | 2023,浅谈智能运维趋势(二)

    (文末附视频,一键观看精彩内容) 前言: 上文提到了智能运维现状中的变化趋势以及 上文提到了智能运维现状中的变化趋势以及过往误区,老杨认为智能运维的体系化建设还需从抓牢数据治理为起点,以终为始做好规划 ...

最新文章

  1. RxJava 内置多种用于调度的线程类型
  2. PointNet++:(1)网络完成的任务分析
  3. 必须安利的KubernetesDevOps工具
  4. Kafka设计解析(二):Kafka High Availability (上)
  5. Android 动态生成 EditTest
  6. 轻量级网络主干综述 20种
  7. 微信小程序设置云函数使用的环境
  8. java 带点的字符串处理,关于android:java中字符串上带点的分割函数
  9. DataTable RowFilter 过滤数据
  10. code vs1517 求一次函数解析式(数论 纯数学知识)
  11. 你可能会用到的 Mock 小技巧
  12. 汇编学习--7.16--直接定址表
  13. 学术会议论文查重吗_会议论文会不会进行摘要查重?
  14. DIV+CSS页面布局
  15. excel快速便捷批量填充
  16. 【虚拟机数据恢复】误删除VMware虚拟机vmdk文件的数据恢复案例
  17. 夜神模拟器 Nox Player 雷电模拟器 掉线 连不上 运行不显示的解决方案
  18. JavaScript设计模式总汇
  19. 创造与魔法服务器维护后必刷鸟吗,创造与魔法云斑鹦鸟位置必刷点2020 刷新时间和地点介绍...
  20. Windows 10 虚拟桌面切换

热门文章

  1. Stata+R: 一文读懂中介效应分析
  2. 分水岭算法 matlab实现
  3. 最全MD5 密码破解 碰撞 网站
  4. 如何自己写一个CNV分析软件?
  5. 看淘宝“舞象”,微商式微
  6. Linux的grep命令源码详解,Linux下的grep命令详解
  7. Qt Creator使用clang-format格式化代码
  8. steam授权_Epic喜+1:塔洛斯的法则|Steam上周销量榜出炉|格力折叠屏手机专利授权...
  9. 蓝桥杯题解 时间显示 Java答案
  10. maple的Linux安装步骤,[原创]CentOS6.0下安装Freeiris2/Asterisk全程指导教程