IndexedDB数据库的基本使用

原文地址点击跳转原文 IndexedDB数据库的基本使用

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

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

window.indexedDB用于判断当前浏览器是否至此 indexedDB ,返回 IDBFactory 对象
这里写图片描述

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(){
	// 连接未关闭
};

如果同时 open 一个数据库,但是版本号不一样,最终生成的数据库会以高版本进行显示

// 同时打开同一个数据库 但是版本号不一致
window.indexedDB.open("demoIndexDB",2);
window.indexedDB.open("demoIndexDB",3);

最终生成的数据库版本为:3

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("获取数据错误");
	};
};

这里写图片描述

- 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("遍历数据错误");
	};
	
	
};

返回结果:
返回结果

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");

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

这里写代码片

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();
    这里写图片描述
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)
    
  2. 利用索引进行多条件查询
    利用索引与游标可以实现多条件查询数据

    // 创建索引
    store.createIndex('myindex', ['name','age'], {unique:false}); 
    // 利用创建的索引查询数据
    var transaction = db.transaction('person','readonly'); 
        var store = transaction.objectStore('person'); 
        var index = store.index('myindex'); 
        // 这里传入的数据 就是具体查询的值 和你创建索引时指定 key 一一对应
        var request1 = index.openCursor(IDBKeyRange.only(["yanwu2", 24]),"next"); 
        request1.onsuccess = function(event) {
            var cursor = event.target.result;
            // 对获取的值进行遍历 返回的数据并不是一个数组
            if (cursor){//如果存在
                var stu = cursor.value;
                console.log(stu);
                cursor.continue();//继续下一个
            }
        }
    }
    

    数据源:
    查询结果:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值