indexedDB
相对于html5 中提到 web SQL Database,w3c已经明确声明放弃对其的继续支持,开始支持新的客户端数据库 indexedDB ,indexedDB 是一种noSQL 的数据库,并将利用 objectStore 来代替 传统数据库中 table 的概念。下面将通过代码来具体熟悉下 indexedDB 及其操作。
1、创建一个数据库。
//使浏览器都兼容 indexedDB,其实现在大多浏览器均以支持,包括360,QQ,FF,chrome 但是IE7-IE9;并不支持。
var indexedDB = window.indexedDB || window.webkitIndexDB || window.mozIndexedDB || window.msIndexedDB;
//创建一个数据库(打开一个数据库)
var request = indexedDB.open("admin",1);
//window.indexedDB.open(dbname,version), 我们通过这个方法创建了一个数据库(如果该数据库之前就存在,此操作则为打开一个数据库。) dbname :数据库的名称; version :数据库的版本号,该版本号在 初始化数据库是可选的,其默认值为 1;
2、相关的事件处理。
//indexedDB 中的相关操作是异步的,既是基于请求——响应的模式,因此这里会有一些简单的回调函数 onerror 、onsuccess 、 onupgradeneeded,我们将在IDBOpenDBRequest对象(request),上面调用这些方法
request = indexedDB.open("admin",2);
request.onupgradeneeded = function() {
alert('onupgradeneeded 事件被调用');
};
request.onsuccess = function() {
alert('onsuccess 事件被调用');
};
request.onerror = function() {
alert('onerror 事件被调用');
};
//函数的相关简单说明:onerror:当操作失败时(这里是创建数据库失败,或者是打开数据库失败,由于以后的操作中也会用到 onerror、onsuccess 事件,所以这里用"操作" ),onerror 事件将会被触发, onupgradeneeded:当创建一个数据库,或者是数据库版本更新时,会触发 onupgradeneeded 事件(在上例中,我们更新了 "admin" 数据库的版本号,所以 onupgradeneeded 事件会被触发),当然我们也可以在这里初始化我们的数据库信息, onsuccess : 当操作成功时,会触发onsuccess 事件。
3、相关的数据库处理
提及数据库的相关处理,当然就是简单的增、删、改、查了,不过在此之前,我们必须明确一些简单的概念。
objectStore : 由于 indexedDB 是noSQL的一种数据库,因此,他并没有传统数据库中 table的概念,但是他包含了 objectStore,可以帮助我们完成操作。对于 objectStore 我所理解的就是“对象商店”,当然就是用来储藏对象的喽,那对象不就是大家熟悉的 “{ }”嘛,而对象里面的当然就是要储存的数据啦。有过SQL数据库编程的童鞋可以将他理解成 table , 并且 objectStore 与 table 有一点是相同的,即一个数据库中可以有多个objectStore 。
键: 在这里的键值,我将它理解为 SQL数据库中的“主键”吧,但是在 objectStore 中 ,键有 2 种,其对储存对象的要求是不同的;下面对使用情况作简要的说明:
键类型 适用场景
不使用 任意值,但是每添加一条数据的时候需要指定键参数
Key Path 所储存的对象必须是 javascript 对象, 并且这个对象中必须 包含一个与 Key Path 值相同的属性。
Key Generator 所储存的对象可以包含任何类型的值,并且这个值会自增长,
Key Path/Key Generator 所储存的对象必须是 javascript 对象, 通常情况产生一个新键,并且产生的这个新键的值要与 KeyPath 的名字相同。如果对象中有keyPath指定的属性则不生成新的键值,如果没有自动生成递增键值,填充keyPath指定属性
事务:在indexedDB 中所有的操作都是基于事务来进行的,这里有些不同于SQL数据库的操作。
添加数据:
request.onsuccess = function(event) {
var db = event.target.result; //这里通过 event.target.result 来取得数据库对象(db)。
var objectStore = db.createObjectStore("books",{keyPath:"id"}); //------这里创建了一个数据对象,第一个参数为“数据商店”的名称,第二个参数为其键。
objectStore.createIndex("name","name",{unique:false}); //创建索引,便于以后的查找,第一个参数为索引名称(就是以数据对象中的某一个属性为索引),第二个参数为自定义的其值。unique 为约束,代表在数据对象中,其值必须是唯一的。
objectStore.createIndex("authorTel","authorTel",{unique:true});
objectStore.transaction.oncomplete = function(event) {
var bookStore = db.transaction(["books"],"readwrite").objectStore("books"); //这里表示在 books “的数据商店” 中,开启一个读写的事务,此外还有:read 只读;versionchange 版本更新
bookStore.add({id : 1, name : "Quarry Memrroes", author : "Fred", authorTel : "12345"});
bookStore.add({id : 2, name : "Water Buffaloes", author : "Fred", authorTel : "67890"});
bookStore.add({id : 3, name : "Bedrock Nights", author : "Barney", authorTel : "345678"});
};
};
获取数据:
基于主键检索:
request.onsuccess = function(event) {
var db = event.target.result;
var bookStore = db.transaction(["books"],"readwrite").objectStore("books"); //该操作如上,在 books “数据商店” 上,开启一个事务。
var fetch = bookStore.get(3); //这里是获取主键(这里就是 id)的那条数据对象,也可以理解成是一条记录吧!
fetch.onerror = function() { //这里 error 及下面的 success 函数, 和上面讲述的作用相同,不再赘述了。
alert("failed");
};
fetch.onsuccess = function() {
if(fetch.result) { // fetch.result 中,保存着我们所检索的那条数据对象,
alert(fetch.result.name); // 取得那个数据对象中的 name 属性值。
} else {
alert("Not found");
}
};
};
基于索引检索:
request.onsuccess = function(event) {
var db = event.target.result;
var index = db.transaction(["books"],"readwrite").objectStore("books").index('name'); //这里获取到相应的键名;
var fetch = index.get("Bedrock Nights");
fetch.onerror = function() {
alert("failed");
};
fetch.onsuccess = function() {
if(fetch.result) {
alert(fetch.result.id);
} else {
alert("Not found");
}
};
};
这两者的差别并不大,这里就不再赘述了。
更新数据:
request.onsuccess = function(event) {
var db = event.target.result;
var objectStore = db.transaction(["books"],"readwrite").objectStore("books"); //该操作如上,在 books “数据商店” 上,开启一个事务。
var fetch = objectStore.get(1); //首先先要获取到那条数据对象
fetch.onerror = function() {
alert("Failed");
};
fetch.onsuccess = function() {
var data = fetch.result;
data.name = "xxxxxxx"; //更新那条数据对象中指定属性的值
var requestUpdate = objectStore.put(data); //更改成功后,再将它重新加进去。
requestUpdate.onerror = function() {
alert("change Failed");
};
requestUpdate.onsuccess = function() {
alert("OK");
};
}
};
删除数据:
request.onsuccess = function(event) {
var db = event.target.result;
var objectStore = db.transaction(["books"],"readwrite").objectStore("books"); //该操作如上,在 books “数据商店” 上,开启一个事务。
var deleteObj = objectStore.delete(1); //删除 id 为 1 的那条数据对象
deleteObj.onerror = function() {
alert("failed");
};
deleteObj.onsuccess = function() {
alert("OK");
};
};
4、游标的使用:
当我们使用 get( ) 方法进行检索数据时,必须是要知道要查询的那个数据对象的一些信息的(比如上例中的 id、name),但是如果我们无法知道那些信息,但还是需要查询数据时,这时候我们就会用到“游标”,来帮助我们来遍历查询数据。下面是具体的示例:
简单使用游标查询:
request.onsuccess = function(event) {
var db = event.target.result,
var objectStore = db.transaction(["books"],"readwrite").objectStore("books"); //该操作如上,在 books “数据商店” 上,开启一个事务。
objectStore.openCursor().onsuccess = function(event) { //通过 openCursor() 方法,开启游标
var cursor = event.target.result;
if(cursor) {
alert(cursor.value.name); //这里 cursor.value 对象中,保存着我们的数据对象,有兴趣的话,可以打印出 cursor 具体查看( console.log(cursor) );
cursor.continue(); //使游标逐步的往下进行
} else {
alert("No more entries");
}
};
};
结合索引利用游标进行查询:
request.onsuccess = function(event) {
var db = event.target.result,
var index = db.transaction(["books"],"readwrite").objectStore("books").index("name");
index.openCursor().onsuccess = function(event) { //通过 openCursor() 方法,开启游标
var cursor = event.target.result;
if(cursor) {
alert(cursor.value.id);
cursor.continue(); //使游标逐步的往下进行
} else {
alert("No more entries");
}
};
};
这里的结合索引利用游标查询,即是两种方法的一种综合应用,并不具有新的意义,前面都已经讲过了,这里就不在详细说明了。
指明游标的方向和范围进行查询
index.openCursor()/index.openKeyCursor()方法在不传递参数的时候会获取object store所有记录,像上面例子一样我们可以对搜索进行筛选
可以使用key range 限制游标中值的范围,把它作为第一个参数传给 openCursor() 或是 openKeyCursor()
IDBKeyRange.only(value):只获取指定数据
IDBKeyRange.lowerBound(value,isOpen):获取最小是value的数据,第二个参数用来指示是否排除value值本身,也就是数学中的是否是开区间
IDBKeyRange.upperBound(value,isOpen):和上面类似,用于获取最大值是value的数据
IDBKeyRange.bound(value1,value2,isOpen1,isOpen2):不用解释了吧
在这里PS下,关于JavaScript中字符比较的问题。。。附上链接 http://www.2cto.com/kf/201408/324339.html
游标方向:游标的方向默认当然是向下走的了。但是您也可以使用 prev 使他向前。 当然还有 nextunique,prevunique,其用于过滤数据对象中重复的数据。
request.onsuccess = function(event) {
var db = event.target.result;
var index = db.transaction(["books"],"readwrite").objectStore("books").index("name"); //这里必须要使用索引
var lowerBoundKeyRange = IDBKeyRange.lowerBound("Water Buffaloes",true);
index.openCursor(lowerBoundKeyRange).onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
alert(cursor.value.id);
cursor.continue();
}
}
};
这里要对.openCursor(range, direction ) 函数做简单的说明,第一个参数指定查询的范围,第二个参数指明查询的方向,如果只想指明查询方向,第一个参数可以设置为 null;
当使用完数据库后应该调用 db.close( ),及时的关闭数据库。
5、删除数据库:
request.onsuccess = function(event) {
indexedDB.deleteDatabase("admin"); //调用indexedDB.deleteDatabase(dbname); 用于删除数据库;
};
PS: indexedDB 是遵守同源策略的,意味着您不能跨域去操作这些信息。
- 【基于WinForm+Access局域网共享数据库的项目总结】之篇二:WinForm开发扇形图统计和Excel数据导出
篇一:WinForm开发总体概述与技术实现 篇二:WinForm开发扇形图统计和Excel数据导出 篇三:Access远程连接数据库和窗体打包部署 [小记]:最近基于WinForm+Access数据库 ...
- 【基于WPF+OneNote+Oracle的中文图片识别系统阶段总结】之篇二:基于OneNote难点突破和批量识别
篇一:WPF常用知识以及本项目设计总结:http://www.cnblogs.com/baiboy/p/wpf.html 篇二:基于OneNote难点突破和批量识别:http://www.cnblog ...
- 《高性能javascript》 领悟随笔之-------DOM编程篇(二)
<高性能javascript> 领悟随笔之-------DOM编程篇二 序:在javaSctipt中,ECMASCRIPT规定了它的语法,BOM实现了页面与浏览器的交互,而DOM则承载着整 ...
- SQL Server调优系列玩转篇二(如何利用汇聚联合提示(Hint)引导语句运行)
前言 上一篇我们分析了查询Hint的用法,作为调优系列的最后一个玩转模块的第一篇.有兴趣的可以点击查看:SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行) 本篇继续玩转模块 ...
- php基础篇-二维数组排序 array_multisort
原文:php基础篇-二维数组排序 array_multisort 对2维数组或者多维数组排序是常见的问题,在php中我们有个专门的多维数组排序函数,下面简单介绍下: array_multisort(a ...
- C蛮的全栈之路-node篇(二) 实战一:自动发博客
目录 C蛮的全栈之路-序章 技术栈选择与全栈工程师C蛮的全栈之路-node篇(一) 环境布置C蛮的全栈之路-node篇(二) 实战一:自动发博客 ---------------- 我是分割线 ---- ...
- 【SSRS】入门篇(二) -- 建立数据源
原文:[SSRS]入门篇(二) -- 建立数据源 通过 [SSRS]入门篇(一) -- 创建SSRS项目 这篇,我们建立了一个SSRS项目: 接下来,我们以 AdventureWorks2012 示例 ...
- 【转】java提高篇(二)-----理解java的三大特性之继承
[转]java提高篇(二)-----理解java的三大特性之继承 原文地址:http://www.cnblogs.com/chenssy/p/3354884.html 在<Think in ja ...
- CYQ.Data 轻量数据层之路 使用篇二曲 MAction 数据查询(十三)----002
原文链接:https://blog.csdn.net/cyq1162/article/details/53303390 前言说明: 本篇继续上一篇内容,本节介绍所有相关查询的使用. 主要内容提要: 1 ...
随机推荐
- 加入收藏夹的js代码(求兼容chrome浏览器的代码)
从网上找了加入收藏夹的js代码,但不兼容chrome,不知道有没有兼容chrome的相关代码,希望有知道的告诉一下,谢谢! 代码如下 $("#id").click(function ...
- Rikka with Chess(规律)
Rikka with Chess Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- iOS 使用Method Swizzling隐藏Status Bar
在iOS 6中,隐藏Status Bar很的简单. // iOS 6及曾经,隐藏状态栏 [[UIApplication sharedApplication] setStatusBarHidden:YE ...
- C++ Primer 读书笔记 第2章 变量和基本类型
C++ Primer 第二章 变量和基本类型 2.1 基本内置类型 C++定义了一组表示整数.浮点数.单个字符和布尔值的算术类型(arithmetic type),此外还定义了Void类型. 算术类型 ...
- HTML系列(三):文字设置
一.标题 标题的h1到h6标签,这里不再赘述.值得一提的是,H5中新定义了一个元素<hgroup>,用来将标题和副标题群组.一般在header里将一组标题组合在一起,变成一个区块: < ...
- 使用Spire PDF for .NET将HTML转换成PDF文档
目录 开发环境说明 Spire PDF for .NET (free edition)体验 资源下载 开发环境说明 Microsoft Visual Studio 2013 Ultimate Edit ...
- jjjjQuery选择器
此文为作者自用复习文章 jQuery选择器: 它不仅继承了CSS选择器简洁的语法, 还继承了其获取页面便捷高效的特点, 它还拥有更加完善的处理机制: 但jQuery选择器获取元素后,为该元素添加的是行 ...
- Servlet基础知识(一)——Servlet的本质
什么是Servlet: Servlet是运行在web服务器端(web容器,如tomcat)的程序,它与Applet相对,Applet是运行在客户端的程序. Servlet的主要作用是处理客户端的请求, ...
- 窗口嵌入到另一个窗口(VC和QT都有)
1.用vc新建一个dialog1工程.属性默认. 2.insert一个dialog2,改为child. 3.在dialog1中包含dialog2头文件,在一个按钮事件中显示dialog2: Cdial ...
- JPEGOPTIM压缩优化
有关JPEGOPTIM JPEGOPTIM是CDN供应商Akamai开发的一个图片人优化的开源小工具. 它有较好的图片压缩效果(压缩比.图片质量), 比PHP的GD库算法要好. 详细的介绍可以看这个文 ...