微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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',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);
            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,{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,'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,'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'); 
}

感谢博主尊重原创
最后标明转载处 http://www.cnblogs.com/dolphinX/p/3415761.html

另外我自己个人加点关于索引
索引的创建主要在onupgradeneeded回调函数中创建,一般跟在创建该表的代码下面。如:

animals = db.createObjectStore("animal",{keyPath:"_id",autoIncrement:true});
               animals.createIndex(animal,"_id",{unique:false});

上面第一行是创建一张表,表名为animal,主键为 _id,设置为自增长。第二行是为该表创建索引,参数值为createIndex(name: String,keyPath: String,optionalParameters: IDBIndexParameters): IDBIndex这是官方说明。第一个参数为表名,第二个是索引值,第三个是判断索引参数是否是唯一的。其实索引就这么简单。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。