浏览器端数据库IndexedDB

1.概念

IndexedDB是一种轻量级NoSQL(Not Only SQL,泛指非关系型)数据库,用来持久化大量客户端数据。

他可以让Web应用程序具有非常强大的查询能力,并且可以离线工作。

INdexedDB的数据操作直接使用JS脚本,不依赖SQL语句,操作返回均采用异步。

而localStorage和sessionStorage对象是采用同步技术实现少量客户端数据存储。

一个网站可能有一个或多个IndexedDB数据库,每个数据库必须有唯一的名称。

WebStorage(即localStorage和sessionStorage)可以用来存储键值对,然而它无法提供按顺序检索、高性能地按值查询或存储重复的键的功能。

2.使用IndexedDB

基本步骤

  1. 打开数据库并且开始一个事物
  2. 创建一个对象仓库(Object Storage)
  3. 创建一个请求来执行一些数据库操作(如增加或提取数据)
  4. 通过监听正确类型的DOM事件以等待操作完成
  5. 在操作结果上进行一些操作(可以在request对象中找到)

判断浏览器是否支持IndexedDB数据库

var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB;
//获得IndexedDB对象
if(window.indexedDB){
    alert("您的浏览器支持IndexedDB数据库");
}
else{
    alert("您的浏览器不支持IndexedDB数据库");
}

数据库创建与打开

使用window.indexedDB.open(DBName, DBVersion);来打开数据库(DBName为数据库名,DBVersion为数据库版本号)

var request = window.indexedDB.open("Mybooks", 2);

var request = window.indexedDB.open("Mybooks", 2);
			request.onerror = function(event){
				alert("数据库连接失败:" + event.target.errorCode);
			}
			request.onsuccess = function(event){
				db = event.target.result;
                //连接成功时获取数据库对象(也可以用request.result)
				alert("数据库连接成功!")
			}
			request.onupgradeneeded = function(event){
				//当此数据库创建前不存在时,进行初始化
				var db = request.result;
				var store = db.createObjectStore("books", {keyPath:"isbn"});
				var titleIndex = store.createIndex("by_title", "title", {unique:"true"});
				var anotherIndex = store.createIndex("by_author", "author");
				store.put({title:"计算机组成原理(修订版)", author:"陈彦亨", isbn:"111111111111"});
				store.put({title:"Java2实用教程", author:"陈彦亨", isbn:"22222222222"});
			}

在数据库连接时,open()方法返回一个IDBOpenRequest对象,调用函数定义在这个对象上(即request)

在连接到数据库后,request会监听三种状态

  • success:打开或创建数据库成功后绑定指定函数
  • error:打开或创建数据库失败后绑定指定函数
  • upgradeneeded:更新数据库后绑定指定函数

upgradeneeded状态是在indexedDB创建新的数据库时和indexedDB.open(DBName,DBVersion)DBVersion发生变化时才能监听得到的状态

创建与删除ObjectStore

ObjectStore(对象仓库、对象存储空间)是IndexedDB数据库的基础,在IndexedDB中并没有关系型数据库中的表,二十使用对象仓库(相当于关系型数据库的表)来存储数据。

db是已连接的数据库对象(var db=request.result)

request是IDBOpenDBRequest对象(var request = window.indexedDB.open(“myBooks”, 1))

1)createObjectStore()方法创建对象仓库

var store = db.createObjectStore(storeName, {keyPath:primaryKey, autoIncrement:true|false});

keyPath为键路径,作为ObjectStore的搜索关键字

var store = db.createObjectStore("books", {keyPath:"isbn});

2)deleteObjectStore()方法删除对象仓库

db.deleteObjectStore(objectStoreName)

db.deleteObjectStore("books");

3)createIndex()方法为对象仓库创建索引

var indexName = store.createIndex(intdex_name, index_key, {unique:true|false});

index_name是索引名称(例如"by_title"表示按标题建立索引),index_key是索引键值名称,{unique:true|false是可选项,表示是否唯一

4)objectStoreName属性检查对象仓库是否存在

objectStoreName属性返回一个DOMStringList对象,里面包含了当前数据库所有“对象仓库”的名称,可以使DOMStringList对象的contains方法,判断数据库是否包含某个“对象仓库”

if(!db.objectStoreNames.contains("books")){db.createObjectStore("books");}

使用事务

需要使用事务在对象存储上执行所有读取和写入操作

1)indexedDB中的事务模式
  • readonly:提供对某个对象的只读访问,在查询对象存储时使用
  • readwrite:提供对某个对象存储的读取和写入访问权
  • versionchange:提供读取和写入访问权来修改对象存储定义,或者创建一个新的对象存储

默认的事务模式为readonly,可以在任何给定时刻打开多个并发的readonly事务,但只能打开一个readwrite事务。因此只有在数据更新时才考虑使用readwrite事务。单独的(表示不能打开任何其他并发事务)versionchange事务操作一个数据库或者对象存储。可以在onupgradeneeded事件处理函数中使用version事务创建、修改或删除一个对象存储,或者将一个索引添加到对象存储。

2)创建事务的基本语法

var transaction = db.transaction(storeName, [transactionmode]);//storeName为对象仓库列表,transactionmode为事务模式

var objectStore = transaction.objectstore(storeName);

transaction()方法返回一个事务对象,objectStore()用于获取指定的对象仓库

var transaction1 = db.transaction("books", "readwrite");//为一个对象仓库创建一个读写事务
var transaction2 = db.transaction(["books", "press"], "readwrite");//为两个对象仓库创建一个读写事务
var objectStore = transaction1.objectStore("books");//获取books对象仓库
3)transaction()方法的事件类型
  • abort:事务中断
  • complete:事务完成
  • error:事务出错
var transaction = db.transaction("books", "readonly");
transaction.oncomplete = function(event){
	alert("数据保存成功");
}
transaction.onerror = function(event){
	console.log("Error", event.target.error.name);
}
transaction.onabort = function(event){
	alert("数据保存失败");
}

数据库的增删改查

1)存储数据准备

var booklists=[{title:"web前端开发技术", author:"陈先生", isbn:"9187302431695}, {title:“计算机组成原理”, author:"林某某“, isbn:"121233221321"}, {title:"Java2实用教程", author:"张某某", isbn:"1232145565667"}];

给books对象仓库定义三个对象存放在booklists数组里,其中没对{}中定义一个对象,每个对象之间用逗号分隔,准备写入到对象仓库中。

2)数据库的增加、更新、删除
objectStore.add(objectName);//添加数据,当关键字存在时数据不会添加
objectStore.put(objectName);//更新数据,当关键字存在时覆盖数据,不存在时会添加数据
objectStore.delete(value);//删除数据,删除指定的关键字对应数据
objectStore.clear();//清楚objectStore
3)数据库的数据读取

var request = objectStore.get(value);//查找数据,根据关键字查找指定的数据

//将已经定义的三个对象添加到对象仓库中
for(var i=0; i<booklists.length; i++){
	request = objectStore.add(booklists[i]);
	request.onerror = function(e){
		console.error("数据库中已有该对象,不能重复添加!");
	}
	request.onsuccess = function(e){
		console.log("对象已经成功存入对象仓库中");
	}
}

遍历数据openCursor()方法

使用对象仓库的openCursor()方法可以实现遍历数据。该方法可以获取游标对象,然后利用游标移动来实现数据遍历。openCursor()方法还可以接受第二个参数表示遍历方向,默认值为next,其他值为prev,nextunique和prevunique。后两个值表示如果遇到重复值,会自动跳过。

1)非索引搜索
var tx = db.transaction(["books"], "readonly");//创建事务对象
var objectStore = tx.objectStore("books");//利用事务对象获取指定的对象仓库
var cursor = objectStore.openCursor();//通过对象仓库打开游标
cursor.onsuccess = function(e){
    var result = e.target.result;//获取结果集
    if(result){
        console.log("key", result.key);//输出键名,如isbn
        console.log("data", result.value);//列出该对象所有属性和方法
        result.continue();//游标移到下一个数据对象上
    }
    else{
        console.log("没有数据可以遍历!");
    }
}
cursor.onerror = function(e){
    console.log("没有数据可以遍历!");
}
2)IDBKeyRange对象

通过索引可以读取指定范围内的数据。使用浏览器原生的IDBKeyRange对象能够生成指定范围的range对象。

如下为生成方法:

  • lowerBound()方法:指定范围的下限
  • upperBound()方法:指定范围的上限
  • bound()方法:指定范围的上下限
  • only()方法:指定范围中只有一个值

第二个参数带上true则表示不包含等于,不带上true则表示大于等于或小于等于

IDBKeyRange.upperbound(x, true);

IDBKeyRane.bound(x, y, true, false)//(x, y];

3)按索引查找数据
var index = objectStore.index(indexName);//indexName为已建立的索引名称(如title,name等)
var cursor = index.openCursor(range);//用IDBKeyRange生成范围range
cursor.addEventListener("success", function(event){
    var result = event.target.result;
    if(result){
        console.log(result.value);
        result.continue();
    }
}, false)
cursor.addEventListener("error", function(event){console.log("失败"), false});
ener("success", function(event){
    var result = event.target.result;
    if(result){
        console.log(result.value);
        result.continue();
    }
}, false)
cursor.addEventListener("error", function(event){console.log("失败"), false});
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
IndexedDB浏览器提供的本地数据库,可以在浏览器中存储结构化数据。下面是 IndexedDB 的基本使用方法: 1. 打开数据库 使用 `indexedDB` 对象的 `open()` 方法打开数据库,如下所示: ``` let request = indexedDB.open('myDB', 1); ``` 其中,第一个参数是数据库名称,第二个参数是数据库版本号。如果数据库不存在,则会创建一个新的数据库。 2. 创建对象仓库 在成功打开数据库的回调方法 `request.onsuccess` 中,可以获取到数据库对象 `event.target.result`,然后使用它的 `createObjectStore()` 方法创建一个对象仓库(即数据表),如下所示: ``` let db = event.target.result; let objectStore = db.createObjectStore('people', { keyPath: 'id' }); ``` 其中,第一个参数是对象仓库的名称,第二个参数是一个对象,包含一个 keyPath 属性和其他可选属性。keyPath 用来指定数据表中的主键。 3. 添加数据 使用事务 `db.transaction()` 开启一个事务,然后使用 `add()` 方法向数据表中添加数据,如下所示: ``` let transaction = db.transaction(['people'], 'readwrite'); let objectStore = transaction.objectStore('people'); let request = objectStore.add({ id: 1, name: 'John Doe' }); ``` 其中,第一个参数是一个数组,包含要访问的对象仓库的名称,第二个参数是事务类型,可以是 'readonly' 或 'readwrite'。`add()` 方法的参数是要添加的数据。 4. 查询数据 使用事务 `db.transaction()` 开启一个事务,然后使用 `get()` 方法查询数据,如下所示: ``` let transaction = db.transaction(['people']); let objectStore = transaction.objectStore('people'); let request = objectStore.get(1); request.onsuccess = function(event) { console.log('Name: ' + event.target.result.name); }; ``` `get()` 方法的参数是要查询的数据的主键值。查询结果保存在 `request.onsuccess` 回调方法中的 `event.target.result` 中。 5. 更新数据 使用事务 `db.transaction()` 开启一个事务,然后使用 `put()` 方法更新数据,如下所示: ``` let transaction = db.transaction(['people'], 'readwrite'); let objectStore = transaction.objectStore('people'); let request = objectStore.put({ id: 1, name: 'Jane Doe' }); ``` `put()` 方法的参数是要更新的数据。 6. 删除数据 使用事务 `db.transaction()` 开启一个事务,然后使用 `delete()` 方法删除数据,如下所示: ``` let transaction = db.transaction(['people'], 'readwrite'); let objectStore = transaction.objectStore('people'); let request = objectStore.delete(1); ``` `delete()` 方法的参数是要删除的数据的主键值。 以上就是 IndexedDB 的基本使用方法。需要注意的是,IndexedDB 的 API 非常庞大,不仅仅包含上面提到的这些方法,还包括索引、游标、版本升级等功能。如果需要更详细的介绍和示例代码,可以参考 MDN 的文档:https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

得过且过的勇者y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值