HTML5本地存储——IndexedDB(一:基本使用)
在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。
事务具有三种模式
- 只读:read,不能修改数据库数据,可以并发执行
- 读写:readwrite,可以进行读写操作
- 版本变更: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(一:基本使用)的更多相关文章
- HTML5本地存储——IndexedDB(二:索引)
在HTML5本地存储——IndexedDB(一:基本使用)中介绍了关于IndexedDB的基本使用方法,很不过瘾,这篇我们来看看indexedDB的杀器——索引. 熟悉数据库的同学都知道索引的一个好处 ...
- HTML5本地存储——IndexedDB
在HTML5本地存储——Web SQL Database提到过Web SQL Database实际上已经被废弃,而HTML5的支持的本地存储实际上变成了 Web Storage(Local Stora ...
- HTML5本地存储——IndexedDB二:索引
HTML5本地存储——IndexedDB(二:索引) 在HTML5本地存储——IndexedDB(一:基本使用)中介绍了关于IndexedDB的基本使用方法,很不过瘾,这篇我们来看看indexed ...
- HTML5本地存储——Web SQL Database与indexedDB
虽然在HTML5 WebStorage介绍了html5本地存储的Local Storage和Session Storage,这两个是以键值对存储的解决方案,存储少量数据结构很有用,但是对于大量结构化数 ...
- HTML5本地存储——Web SQL Database
在HTML5 WebStorage介绍了html5本地存储的Local Storage和Session Storage,这两个是以键值对存储的解决方案,存储少量数据结构很有用,但是对于大量结构化数据就 ...
- [转]HTML5本地存储——Web SQL Database
在HTML5 WebStorage介绍了html5本地存储的Local Storage和Session Storage,这两个是以键值对存储的解决方案,存储少量数据结构很有用,但是对于大量结构化数据就 ...
- HTML5本地存储localStorage与sessionStorage
在最近的项目中用到了html5的本地存储,下面总结一下. 1.html5几种存储形式 本地存储(localStorage && sessionStorage) 离线缓存(applica ...
- HTML5本地存储localStorage与sessionStorage详解
前言 在最近的项目中用到了html5的本地存储,下面总结一下. 1.html5几种存储形式 本地存储(localStorage && sessionStorage) 离线缓存(appl ...
- HTML5本地存储(Local Storage) 的前世今生
长久以来本地存储能力一直是桌面应用区别于Web应用的一个主要优势.对于桌面应用(或者原生应用),操作系统一般都提供了一个抽象层用来帮助应用程序保存其本地数据 例如(用户配置信息或者运行时状态等). 常 ...
随机推荐
- Linux命令学习总结:rm命令
命令简介: 该命令用来删除Linux系统中的文件或目录.通常情况下rm不会删除目录,你必须通过指定参数-r或-R来删除目录.另外rm通常可以将该文件或目录恢复(注意,rm删除文件其实只是将指向数据 ...
- 使用Java实现简单串口通信
最近一门课要求编写一个上位机串口通信工具,我基于Java编写了一个带有图形界面的简单串口通信工具,下面详述一下过程,供大家参考 ^_^ 一: 首先,你需要下载一个额外的支持Java串口通信操作的jar ...
- 搭建自己的PHP框架心得(一)
h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h ...
- Junit测试Controller(MockMVC使用),传输@RequestBody数据解决办法
一.单元测试的目的 简单来说就是在我们增加或者改动一些代码以后对所有逻辑的一个检测,尤其是在我们后期修改后(不论是增加新功能,修改bug),都可以做到重新测试的工作.以减少我们在发布的时候出现更过甚至 ...
- LNMP环境magento常见错误
一.安装报404错误 git clone 下最新代码,跳转到index/install 安装时出现404错误 需要把伪静态规则加到nginx配置文件中: # # The default server ...
- MySql错误代码1045的解决方案
错误代码 1045Access denied for user 'root'@'localhost' (using password:YES) 解决办法是重新设置root用户密码,在Windows平台 ...
- 【2016-11-2】【坚持学习】【Day17】【微软 推出的SQLHelper】
从网络上找到 微软原版本的SQLHelper,很多行代码.认真看了,学习了. 代码: using System; using System.Data; using System.Xml; usin ...
- 【读书笔记《Bootstrap 实战》】3.优化站点资源、完成响应式图片、让传送带支持手势
A.优化站点资源 速度很重要.用户很关心.我们的站点必须加载够快,否则用户就会走人.SEO 也很重要.我们的站点必须加载够快,否者搜索排名就会下降. 明白了这样,我们就来清点一下 [Bootstrap ...
- markdown编辑器
经过一番探索终于找到两个可以实时预览的markdown编辑器 一,sublime text 3 + MarkDown Editing + OmniMarkupPreviwer 安装方法网上均有,这里要 ...
- 第24章 java线程(3)-线程的生命周期
java线程(3)-线程的生命周期 1.两种生命周期流转图 ** 生命周期:**一个事物冲从出生的那一刻开始到最终死亡中间的过程 在事物的漫长的生命周期过程中,总会经历不同的状态(婴儿状态/青少年状态 ...