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应用的一个主要优势.对于桌面应用(或者原生应用),操作系统一般都提供了一个抽象层用来帮助应用程序保存其本地数据 例如(用户配置信息或者运行时状态等). 常 ...
随机推荐
- Hadoop2.5.0 搭建实录
目录: 第一步:准备相关材料 第二步:虚拟机环境搭建 第三步:用户信息 第四步 安装.配置Java环境 第五步 Zookeeper安装配置 第六步 Hadoop安装.配置 第七步:HBase安装部署 ...
- 非root用户的SSH免密登录
在网上找到的教程一般是这样说的 cd ~/.ssh/ # 若没有该目录,请先执行一次ssh localhost ssh-keygen -t rsa # 会有提示,都按回车就可以 cat id_rsa. ...
- Webservice详解
WebService是什么? 1. 基于Web的服务:服务器端整出一些资源让客户端应用访问(获取数据) 2. 一个跨语言.跨平台的规范(抽象) 3. 多个跨平台.跨语言的应用间通信整合的方案(实际) ...
- C++11 - 类型推导auto关键字
在C++11中,auto关键字被作为类型自动类型推导关键字 (1)基本用法 C++98:类型 变量名 = 初值; int i = 10; C++11:auto 变量名 = 初值; auto i ...
- 374&375. Guess Number Higher or Lower 1&2
做leetcode的题 We are playing the Guess Game. The game is as follows: I pick a number from 1 to n. You ...
- 双11遇上ZBrushCore,如此优惠还等什么!
对不起!让大家久等了,ZBrush简体中文版ZBrushCore这次是真的来了,恰逢双11,老板说了,钱不是问题,你们开心就好,特别是热爱3D的单身狗们!你们那么热爱这个行业,1099元/套终身授权使 ...
- markdown编辑器
经过一番探索终于找到两个可以实时预览的markdown编辑器 一,sublime text 3 + MarkDown Editing + OmniMarkupPreviwer 安装方法网上均有,这里要 ...
- golang中的slice翻转存在以及map中的key判断
//slice翻转 func stringReverse(src []string){ if src == nil { panic(fmt.Errorf("the src can't be ...
- CCF考试
第八次CCF考试记录 代码还不知道对不对,过两天出成绩. 成绩出来了,310分. 100+100+100+10+0: 考试13:27开始,17:30结束,提交第4题后不再答题,只是检查前四题的代码 第 ...
- NYOJ 451
光棍节的快乐 描述 光棍们,今天是光棍节.聪明的NS想到了一个活动来丰富这个光棍节. 规则如下: 每个光棍在一个纸条上写一个自己心仪女生的名字,然后把这些纸条装进一个盒子里,这些光 棍依次抽取一张纸条 ...