IndexedDB数据库的基本使用

浏览器的本地存储,一般有Cookie,LocalStorage,webSQL; Cookie 与 LocalStorage 一般用于小数据量的存储,webSQL现阶段已经废弃;现在浏览器本地存储大量数据一般都是用indexedDB数据库;就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。

1.判断浏览器是否支持 indexedDB

window.indexedDB用于判断当前浏览器是否至此 indexedDB ,返回 IDBFactory 对象
IndexedDB数据库的基本使用_第1张图片

if(window.indexedDB){
    //支持
}else{
    //不支持
}

2.打开/新建数据库

window.indexedDB.open(name,vision);
open方法支持打开一个本地数据库
参数:
name: 表示你要打开数据库的名称,不可省略
vision: 表示你打开数据库的版本,可省略

注:
① 当打开数据库时,这个数据库不存在,会自动新建再打开,如果存在,则直接打开。
② vision版本号不能低于当前存在的数据库的版本,否则打开数据库会失败。
③ vision版本号只能是整数

IndexedDB 所有操作都是异步的,防止在操作IndexedDB时,浏览器锁死;open在打开数据库的时候,会产生回调函数;
这里写图片描述
success:打开成功。
error:打开失败。
upgradeneeded:第一次打开该数据库,或者数据库版本发生变化。
blocked:上一次的数据库连接还未关闭。

第一次打开数据库时,会先触发upgradeneeded事件,然后触发success事件。

var req=window.indexedDB.open("db",1);

req.onupgradeneeded=function(){
    //第一次打开
}

req.onsuccess=function(){
    // 成功
};

req.onerror=function(){
    // 失败
};


req.onblocked=function(){
    // 连接未关闭
};

3.indexedDB实例对象的方法

open函数的回调函数接受一个事件对象event作为参数,它的target.result属性就指向打开的IndexedDB数据库。

req.onupgradeneeded=function(e){
    var db=e.target.result;
}

req.onsuccess=function(){
    var db=e.target.result;
};

获得数据库实例以后,就可以用实例对象的方法操作数据库。

4.createObjectStore 创建存储仓库

createObjectStore方法用于创建存放数据的“对象仓库”,相当于一张数据表,参数为名字;如果创建的”对象仓库”已经存在,则会创建失败;

req.onupgradeneeded=function(e){
    var db=e.target.result;
    //创建一个名字为user的对象仓库
    var userObjStore=db.createObjectStore("user");
}

createObjectStore方法还可以接受第二个对象参数,用来设置“对象仓库”的属性。

req.onupgradeneeded=function(e){
    var db=e.target.result;
    //创建一个名字为user的对象仓库,并将其 id 作为该 对象仓库 的主键
    var userObjStore=db.createObjectStore("user",{keyPath:"id"});
}
req.onupgradeneeded=function(e){
    var db=e.target.result;
    //创建一个名字为user的对象仓库,并添加一条自增的数据作为键
    var userObjStore=db.createObjectStore("user",{autoIncrement:true});
}

keyPath:表示所存入对象的id属性用作每条记录的键名(id不能重复),默认值为null,类似于数据表的主键;
autoIncrement:表示,是否使用自动递增的整数作为键名(自增),默认为false。
一般来说,keyPath和autoIncrement属性只要使用一个就够了,如果两个同时使用,表示键名为递增的整数,且对象不得缺少指定属性。

4.objectStoreNames 属性

在使用 createObjectStore 创建一个对象仓库的时候,如果该对象仓库已经存在,则会跑出一个错误,所以一般在创建一个对象仓库之前,需要先进行判断,该对象仓库是否存在;
数据库对象的objectStoreNames属性返回一个DOMStringList对象,里面包含了当前数据库所有“对象仓库”的名称;
使用DOMStringList对象的contains方法,检查数据库中某个“对象仓库”是否存在。这样可以避免重复创建抛出错误。

req.onupgradeneeded=function(e){
    var db=e.target.result;
    if( ! db.objectStoreNames.contains("user")){
        var userObjStore=db.createObjectStore("user",{autoIncrement:true});
    }
}

5.transaction 创建数据库事务

在操作数据库中的数据时,必须先创建一个事务;
transaction方法用于创建数据库事务。
两个参数:
①第一个参数:一个数组,里面是所涉及的是需要操作的对象仓库,通常是只有一个;
②第二个参数:一个表示操作类型的字符串。目前,操作类型只有两种:readonly(只读)和readwrite(读写)。添加数据使用readwrite,读取数据使用readonly。
transaction方法返回一个事务对象,该对象的objectStore方法用于获取指定的对象仓库。

req.onsuccess=function(){
    var db=e.target.result;
    var t=db.transaction(["user"],"readwrite");
    var userStore=t.objectStore("uesr");
};

6.objectStore 操作数据库中的数据

①添加数据:add方法
②读取数据:get方法
③更新记录:put方法
④删除记录:delete方法
⑤遍历数据:openCursor方法

- 添加数据

req.onsuccess=function(e){
    var db=e.target.result;
    var t=db.transaction(["user"],"readwrite");
    var store=t.objectStore("user");
    var addResult=store.add({
        name:"yanwu",
        age:25,
        pid:1001
    });
    addResult.onsuccess=function(){
        console.log("添加成功");
    };
    addResult.onerror=function(){
        console.log("添加失败");
    }
};

这里写图片描述

*添加数据的操作是异步执行的,需要在回调函数中去判断数据是否添加成功。

- put方法
put方法同add方法的使用方法相同,需要注意的是在put数据时,若存在相同的key,则是更新,若不存在相同的key,则是添加。

- get方法
get方法用于获取数据,在没有建立索引的情况下,只能根据数据的key来获取数据;

req.onsuccess=function(e){
    var db=e.target.result;
    var t=db.transaction(["user"],"readwrite");
    var store=t.objectStore("user");

    var getResult=store.get(1);
    getResult.onsuccess=function(e){
        var data=e.target.result;

        console.log(data.name);
        console.log(data.age);
        console.log(data.pid);
    };
    getResult.onerror=function(){
        console.log("获取数据错误");
    };
};

IndexedDB数据库的基本使用_第2张图片

- delete方法
delete方法与get方法的使用方式类似,在没有建立索引的情况下,直接传入key用来删除数据。

-openCursor方法
openCursor方法用来遍历指定仓库中的所有数据,这个操作是异步执行的,所以返回结果会在回调函数中。

req.onsuccess=function(e){
    var db=e.target.result;
    var t=db.transaction(["user"],"readwrite");
    var store=t.objectStore("user");
    var cursor=store.openCursor();
    cursor.onsuccess=function(event){
        var res=event.target.result;
        if(res){
            var key=res.key;
            var value=res.value;
            console.log(key+":"+JSON.stringify(value));
            res.continue();
        }
    };
    cursor.onerror=function(){
        console.log("遍历数据错误");
    };


};

返回结果:
IndexedDB数据库的基本使用_第3张图片

6.索引的使用

在实际的开发过程中,我们的查询业务一般是很复杂的,使用一般的get查询不能满足我们的全部需求,在这里我们就要引入“索引”,有了“索引”之后我们就可以根据某些“特殊属性”来查询数据;

- 创建索引
createIndex()方法用于为仓库对象创建一个索引,接受三个参数:索引名称、属性名、参数对象。

req.onupgradeneeded=function(e){
    var db=e.target.result;//数据库对象
    //判断仓库是否存在
    if(!db.objectStoreNames.contains("user")){
        //创建仓库
        var store=db.createObjectStore("user",{
            autoIncrement:true
        });
        //创建索引
        store.createIndex("nameIndex","name",{unique:false});
        store.createIndex("ageIndex","age",{unique:false});
    }
}

注: unique表示这个索引值在仓库对象中是否唯一

- index方法获取索引
有了索引之后,我们就可以通过索引根据指定的属性来获取数据;index方法可以从仓库对象中返回指定的索引。

var db=myDB.db;
var t=db.transaction(["user"],"readwrite");
var userStore=t.objectStore("user");
var index=userStore.index("ageIndex");

在获取到了指定的索引之后,就可以通过索引来获取数据,这里需要注意的是,获取数据的步骤是异步执行的,只能在回调函数中才能拿到指定的数据。

IndexedDB数据库的基本使用_第4张图片

req.onsuccess=function(e){
    var db=e.target.result;
    var t=db.transaction(["user"],"readwrite");
    var store=t.objectStore("user");
    var index=store.index("ageIndex");
    var request=index.get(20);
    request.onsuccess=function(event){
        var data=event.target.result;
    };
    request.onerror=function(){
        console.log("获取失败");
    };
};

注: 这里需要注意的是,虽然在数据库中,满足条件的数据有多条,但是实际在返回的时候,只返回了第一条满足条件的数据,如果想要获取更多满足条件的数据,则需要用到游标。

- cursor 游标
在indexedDB数据库中,使用游标和使用索引是分不开的;
仓库对象的openCursor方法,用于创建一个游标;
contine方法会使游标按指定方向移动,直到没有数据的时候返回undefined;
使用游标能够遍历整个仓库的数据,这在前面已经介绍过了,这里不再介绍。

- 索引与游标的共同使用

  1. 获取指定值得数据 IDBKeyRange.only();
    IndexedDB数据库的基本使用_第5张图片
req.onsuccess=function(e){
        var db=e.target.result;
        var t=db.transaction(["user"],"readwrite");
        var store=t.objectStore("user");
        var index=store.index("ageIndex");
        //获取age=20的所有数据
        var request=index.openCursor(IDBKeyRange.only(20*1));
        request.onsuccess=function(event){
            var cursor=event.target.result;
            if(cursor){
                var key=cursor.key;
                var primaryKey=cursor.primaryKey;
                var name=cursor.value.name;
                var age=cursor.value.age;
                console.info("key:"+key+","+"primaryKey:"+primaryKey+","+"name:"+name+","+"age:"+age);
                cursor.continue();
            }
        };
        request.onerror=function(event){
            console.log("获取数据错误");
        };
    };

返回的数据:
这里写图片描述

  1. 获取范围数据
    利用游标与索引除了可以获取指定值的所有数据之外,还可以获取在一定范围之内的数据;
//获取 age >= 20 的数据 包含下限值
IDBKeyRange.lowerBound(20)
//     age > 20
IDBKeyRange.lowerBound(20,true)

//获取  age <= 20 的数据  包含上限值
IDBKeyRange.upperBound(20);
//      age < 20
IDBKeyRange.upperBound(20,true);

//获取  20 <= age <= 24 范围内的值,包含界限值
IDBKeyRange.bound(20,24)
//     20 <   age <= 24
IDBKeyRange.bound(20,24,true,false)
//     20 <=  age < 24
IDBKeyRange.bound(20,24,false,true)
//     20 <   age < 24
IDBKeyRange.bound(20,24,true,true)

其余的使用方法均同上。


完整版DEMO下载地址:点击下载

完整版DEMO 码云地址:点击下载

你可能感兴趣的:(前端)