HTML5本地存储——Web SQL Database提到过Web SQL Database实际上已经被废弃,而HTML5的支持的本地存储实际上变成了

Web Storage(Local Storage和Session Storage)与IndexedDB。Web Storage使用简单字符串键值对在本地存储数据,方便灵活,但是对于大量结构化数据存储力不从心,IndexedDB是为了能够在客户端存储大量的结构化数据,并且使用索引高效检索的API。

异步API

在IndexedDB大部分操作并不是我们常用的调用方法,返回结果的模式,而是请求——响应的模式,比如打开数据库的操作

var request=window.indexedDB.open('testDB');

这条指令并不会返回一个DB对象的句柄,我们得到的是一个IDBOpenDBRequest对象,而我们希望得到的DB对象在其result属性中,

这条指令请求的响应是一个 IDBDatabase对象,这就是IndexedDB对象,

除了result,IDBOpenDBRequest接口定义了几个重要属性

  • onerror: 请求失败的回调函数句柄
  • onsuccess:请求成功的回调函数句柄
  • onupgradeneeded:请求数据库版本变化句柄

所谓异步API是指并不是这条指令执行完毕,我们就可以使用request.result来获取indexedDB对象了,就像使用ajax一样,语句执行完并不代表已经获取到了对象,所以我们一般在其回调函数中处理。

创建数据库

刚才的语句已经展示了如何打开一个indexedDB数据库,调用indexedDB.open方法就可以创建或者打开一个indexedDB。看一个完整的处理

function openDB (name) {
var request=window.indexedDB.open(name);
request.onerror=function(e){
console.log('OPen Error!');
};
request.onsuccess=function(e){
myDB.db=e.target.result;
};
} var myDB={
name:'test',
version:1,
db:null
};
openDB(myDB.name);

代码中定义了一个myDB对象,在创建indexedDB request的成功毁掉函数中,把request获取的DB对象赋值给了myDB的db属性,这样就可以使用myDB.db来访问创建的indexedDB了。

version

我们注意到除了onerror和onsuccess,IDBOpenDBRequest还有一个类似回调函数句柄——onupgradeneeded。这个句柄在我们请求打开的数据库的版本号和已经存在的数据库版本号不一致的时候调用。

indexedDB.open()方法还有第二个可选参数,数据库版本号,数据库创建的时候默认版本号为1,当我们传入的版本号和数据库当前版本号不一致的时候onupgradeneeded就会被调用,当然我们不能试图打开比当前数据库版本低的version,否则调用的就是onerror了,修改一下刚才例子

function openDB (name,version) {
var version=version || 1;
var request=window.indexedDB.open(name,version);
request.onerror=function(e){
console.log(e.currentTarget.error.message);
};
request.onsuccess=function(e){
myDB.db=e.target.result;
};
request.onupgradeneeded=function(e){
console.log('DB version changed to '+version);
};
} var myDB={
name:'test',
version:3,
db:null
};
openDB(myDB.name,myDB.version);

由于刚才已经创建了版本为1的数据库,打开版本为3的时候,会在控制台输出:DB version changed to 3

关闭与删除数据库

关闭数据库可以直接调用数据库对象的close方法

function closeDB(db){
db.close();
}

删除数据库使用indexedDB对象的deleteDatabase方法

function deleteDB(name){
indexedDB.deleteDatabase(name);
}

简单调用

var myDB={
name:'test',
version:3,
db:null
};
openDB(myDB.name,myDB.version);
setTimeout(function(){
closeDB(myDB.db);
deleteDB(myDB.name);
},500);

由于异步API愿意,不能保证能够在closeDB方法调用前获取db对象(实际上获取db对象也比执行一条语句慢得多),所以用了setTimeout延迟了一下。当然我们注意到每个indexedDB实例都有onclose回调函数句柄,用以数据库关闭的时候处理,有兴趣同学可以试试,原理很简单,不演示了。

object store

有了数据库后我们自然希望创建一个表用来存储数据,但indexedDB中没有表的概念,而是objectStore,一个数据库中可以包含多个objectStore,objectStore是一个灵活的数据结构,可以存放多种类型数据。也就是说一个objectStore相当于一张表,里面存储的每条数据和一个键相关联。

我们可以使用每条记录中的某个指定字段作为键值(keyPath),也可以使用自动生成的递增数字作为键值(keyGenerator),也可以不指定。选择键的类型不同,objectStore可以存储的数据结构也有差异

键类型 存储数据
不使用 任意值,但是没添加一条数据的时候需要指定键参数
keyPath Javascript对象,对象必须有一属性作为键值
keyGenerator 任意值
都使用 Javascript对象,如果对象中有keyPath指定的属性则不生成新的键值,如果没有自动生成递增键值,填充keyPath指定属性

事务

在对新数据库做任何事情之前,需要开始一个事务。事务中需要指定该事务跨越哪些object store。

事务具有三种模式

  1. 只读:read,不能修改数据库数据,可以并发执行
  2. 读写:readwrite,可以进行读写操作
  3. 版本变更:verionchange
var transaction=db.transaction([students','taecher']);  //打开一个事务,使用students 和teacher object store
var objectStore=transaction.objectStore('students'); //获取students object store

给object store添加数据

调用数据库实例的createObjectStore方法可以创建object store,方法有两个参数:store name和键类型。调用store的add方法添加数据。有了上面知识,我们可以向object store内添加数据了

keyPath

因为对新数据的操作都需要在transaction中进行,而transaction又要求指定object store,所以我们只能在创建数据库的时候初始化object store以供后面使用,这正是onupgradeneeded的一个重要作用,修改一下之前代码

function openDB (name,version) {
var version=version || 1;
var request=window.indexedDB.open(name,version);
request.onerror=function(e){
console.log(e.currentTarget.error.message);
};
request.onsuccess=function(e){
myDB.db=e.target.result;
};
request.onupgradeneeded=function(e){
var db=e.target.result;
if(!db.objectStoreNames.contains('students')){
db.createObjectStore('students',{keyPath:"id"});
}
console.log('DB version changed to '+version);
};
}

这样在创建数据库的时候我们就为其添加了一个名为students的object store,准备一些数据以供添加

var students=[{
id:1001,
name:"Byron",
age:24
},{
id:1002,
name:"Frank",
age:30
},{
id:1003,
name:"Aaron",
age:26
}];
function addData(db,storeName){
var transaction=db.transaction(storeName,'readwrite');
var store=transaction.objectStore(storeName); for(var i=0;i<students.length;i++){
store.add(students[i]);
}
} openDB(myDB.name,myDB.version);
setTimeout(function(){
addData(myDB.db,'students');
},1000);

这样我们就在students object store里添加了三条记录,以id为键,在chrome控制台看看效果

keyGenerate

function openDB (name,version) {
var version=version || 1;
var request=window.indexedDB.open(name,version);
request.onerror=function(e){
console.log(e.currentTarget.error.message);
};
request.onsuccess=function(e){
myDB.db=e.target.result;
};
request.onupgradeneeded=function(e){
var db=e.target.result;
if(!db.objectStoreNames.contains('students')){
db.createObjectStore('students',{autoIncrement: true});
}
console.log('DB version changed to '+version);
};
}

剩下的两种方式有兴趣同学可以自己摸索一下了

查找数据

可以调用object store的get方法通过键获取数据,以使用keyPath做键为例

function getDataByKey(db,storeName,value){
var transaction=db.transaction(storeName,'readwrite');
var store=transaction.objectStore(storeName);
var request=store.get(value);
request.onsuccess=function(e){
var student=e.target.result;
console.log(student.name);
};
}

更新数据

可以调用object store的put方法更新数据,会自动替换键值相同的记录,达到更新目的,没有相同的则添加,以使用keyPath做键为例

function updateDataByKey(db,storeName,value){
var transaction=db.transaction(storeName,'readwrite');
var store=transaction.objectStore(storeName);
var request=store.get(value);
request.onsuccess=function(e){
var student=e.target.result;
student.age=35;
store.put(student);
};
}

删除数据及object store

调用object store的delete方法根据键值删除记录

function deleteDataByKey(db,storeName,value){
var transaction=db.transaction(storeName,'readwrite');
var store=transaction.objectStore(storeName);
store.delete(value);
}

调用object store的clear方法可以清空object store

function clearObjectStore(db,storeName){
var transaction=db.transaction(storeName,'readwrite');
var store=transaction.objectStore(storeName);
store.clear();
}

调用数据库实例的deleteObjectStore方法可以删除一个object store,这个就得在onupgradeneeded里面调用了

if(db.objectStoreNames.contains('students')){
db.deleteObjectStore('students');
}

最后

这就是关于indexedDB的基本使用方式,很多同学看了会觉得很鸡肋,和我们正常自己定义个对象使用没什么区别,也就是能保存在本地罢了,这是因为我们还没有介绍indexedDB之所以称为indexed的杀器——索引,这个才是让indexedDB大显神通的东西,下篇我们就来看看这个杀器。

HTML5本地存储——IndexedDB(一:基本使用)的更多相关文章

  1. HTML5本地存储——IndexedDB(二:索引)

    在HTML5本地存储——IndexedDB(一:基本使用)中介绍了关于IndexedDB的基本使用方法,很不过瘾,这篇我们来看看indexedDB的杀器——索引. 熟悉数据库的同学都知道索引的一个好处 ...

  2. HTML5本地存储——IndexedDB

    在HTML5本地存储——Web SQL Database提到过Web SQL Database实际上已经被废弃,而HTML5的支持的本地存储实际上变成了 Web Storage(Local Stora ...

  3. HTML5本地存储——IndexedDB二:索引

    HTML5本地存储——IndexedDB(二:索引)   在HTML5本地存储——IndexedDB(一:基本使用)中介绍了关于IndexedDB的基本使用方法,很不过瘾,这篇我们来看看indexed ...

  4. HTML5本地存储——Web SQL Database与indexedDB

    虽然在HTML5 WebStorage介绍了html5本地存储的Local Storage和Session Storage,这两个是以键值对存储的解决方案,存储少量数据结构很有用,但是对于大量结构化数 ...

  5. HTML5本地存储——Web SQL Database

    在HTML5 WebStorage介绍了html5本地存储的Local Storage和Session Storage,这两个是以键值对存储的解决方案,存储少量数据结构很有用,但是对于大量结构化数据就 ...

  6. [转]HTML5本地存储——Web SQL Database

    在HTML5 WebStorage介绍了html5本地存储的Local Storage和Session Storage,这两个是以键值对存储的解决方案,存储少量数据结构很有用,但是对于大量结构化数据就 ...

  7. HTML5本地存储localStorage与sessionStorage

    在最近的项目中用到了html5的本地存储,下面总结一下. 1.html5几种存储形式 本地存储(localStorage && sessionStorage) 离线缓存(applica ...

  8. HTML5本地存储localStorage与sessionStorage详解

    前言 在最近的项目中用到了html5的本地存储,下面总结一下. 1.html5几种存储形式 本地存储(localStorage && sessionStorage) 离线缓存(appl ...

  9. HTML5本地存储(Local Storage) 的前世今生

    长久以来本地存储能力一直是桌面应用区别于Web应用的一个主要优势.对于桌面应用(或者原生应用),操作系统一般都提供了一个抽象层用来帮助应用程序保存其本地数据 例如(用户配置信息或者运行时状态等). 常 ...

随机推荐

  1. SQL Server 2012安装错误案例:Error while enabling Windows feature: NetFx3, Error Code: -2146498298

    案例环境: 服务器环境 :    Windows Server 2012 R2 Standard 数据库版本 :    SQL Server 2012 SP1 案例介绍:   在Windows Ser ...

  2. SQL SERVER 2012启动失败 because upgrade step 'SSIS_hotfix_install.sql' 失败

    有台数据库服务器(开发服务器),开发人员邮件告诉我,SSMS连接不了这台服务器,远程登录后,发现SQL SERVER的服务停止了,启动服务时报错,服务启动不了.检查错误日志发现下面一些信息 2015- ...

  3. HDFS开发实例

    1.列出HDFS中的文件 package com.hdfs.test; import java.io.BufferedReader; import java.io.IOException; impor ...

  4. Oracle索引梳理系列(六)- Oracle索引种类之函数索引

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  5. 尽量不要用ad,adv···,advertisement 这些关键词命名

    html dom,文件夹名称,文件名称·······,都尽量不用ad,adv···,advertisement  这些关键词! 为嘛呢? 因为会被浏览器的广告插件自动给屏蔽掉. 我的网站中有一个广告管 ...

  6. 【2016-10-25】【坚持学习】【Day12】【WPF】【Telerik】【VirtualtionData 虚拟化数据】

    VirtualQueryableCollectionView When working with the UI components that enable UI Virtualization, yo ...

  7. Qt 之 饼图

    Qt 库由许多模块组成,其中的 Qt Charts,包含了一系列图表组件. 1  饼图 (pie chart) 1.1  Charts 模块 .pro 中添加如下语句: QT += charts 头文 ...

  8. MySQL 笔记2

    -- *************一.数据约束********************---- -- 1.1 默认值 CREATE TABLE student( id INT, NAME ), addr ...

  9. UITabBarController的创建与自定义TarBar---学习笔记三

    代码如下: #import <UIKit/UIKit.h> @interface BSJTabBarViewController : UITabBarController @end #im ...

  10. Zip加密

    http://www.cnblogs.com/kgdxpr/archive/2013/08/01/3230174.html