Indexed Database API,简称 IndexedDB,是在浏览器中保存结构化数据的一种数据库。
IndexedDB 的思想是创建一套 API,方便保存和读取 JavaScript 对象,同时还支持查询及搜索。(API 超级多~)
此外,IndexedDB 也遵循同源策略,并且大小也有限制。和 localStorage 相似,若非手动删除或调用 JavaScript 方法删除,IndexedDB 的数据会一直存在。
大小限制可以看这里:A research report on browser storage
IndexedDB API 汇总(只列出主要的)
- window.indexedDB: 一个 IDBFactory 对象
IDBFactory 对象
- IDBFactory.open(name[,version]): 发送一个连接指定数据库的请求
- name: 数据库的名称
- version: 可选值,数据库的版本,若未指定,默认为 1
- 这个方法返回一个 IDBOpenDBRequest 对象
- IDBFactory.deleteDatabase(name): 删除指定的数据库
- 这个方法也返回一个 IDBOpenDBRequest 对象
- IDBFactory.cmp(): 比较数据库。。没用过
IDBOpenDBRequest 对象
- IDBOpenDBRequest.onsuccess: 请求成功时触发
- event.target: 指向当前的 IDBOpenDBRequest 对象
- event.target.result: 获取数据库对象(一个 IDBDatabase 对象)
- IDBOpenDBRequest.onerror: 请求发生错误时触发(比如请求比当前数据库版本低的数据库时会触发)
- event.target: 指向当前的 IDBOpenDBRequest 对象
- event.target.error: 获取发生错误的详细信息
- IDBOpenDBRequest.onblocked: This event is triggered when the upgradeneeded should be triggered because of a version change but the database is still in use (that is, not closed) somewhere, even after the versionchange event was sent.
- IDBOpenDBRequest.onupgradeneeded: 在请求的数据库版本不可用时触发(比如升级数据库,即请求的数据库版本比当前版本高时触发,或者说请求的数据库不存在时触发)
- event.target: 指向当前的 IDBOpenDBRequest 对象
- event.target.result: 获取数据库对象(一个 IDBDatabase 对象)
IDBDatabase 对象
-
属性
- IDBDatabase.name: 返回当前数据库的名称
- IDBDatabase.version: 返回当前数据库的版本
- IDBDatabase.objectStoreNames: 返回一个类数组对象,存储着各个对象存储空间的名称
-
事件
- IDBDatabase.onabort: 获取数据库被拒绝时触发
- IDBDatabase.onclose: 关闭数据库时触发
- IDBDatabase.onerror: 获取数据库失败时触发
- IDBDatabase.onversionchange: 数据库结构发生变化时触发【fired when a database structure change (IDBOpenDBRequest.onupgradeneeded event or IDBFactory.deleteDatabase) was requested elsewhere (most probably in another window/tab on the same computer)】
- IDBDatabase.createObjectStore(name [,optionalObj]): 新建一个对象存储空间(类似数据库中的数据表)
- name: 对象存储空间的名称
- optionalObj: 一个对象,属性 keyPath 声明主关键字;属性 autoIncrement 默认为 false,设置为 true 时可以自动生成唯一的数字
- 主关键字是唯一标识每条数据的信息
- 该方法返回一个 IDBObjectStore 对象
- IDBDatabase.deleteObjectStore(name): 删除指定名称的对象存储空间,什么也不返回
- IDBDatabase.close(): 在所有的数据操作结束后,立即关闭与数据库的连接
- The connection is not actually closed until all transactions created using this connection are complete
- IDBDatabase.transaction(storeName[,mode]): 获取指定的对象存储空间
- storeName: 需要获取的对象存储空间的名称,可以是一个字符串、一个数组(获取多个对象存储空间)
- mode: 权限设置,一个字符串,readonly(只读)、readwrite(可以读写)、readwriteflush(最后这个是非标准,一般不使用)
- 该方法返回一个 IDBTransaction 对象
createObjectStore 和 deleteObjectStore 方法只能在最开始连接数据库的 IDBOpenDBRequest.onupgradeneeded 中进行调用,不能在 IDBOpenDBRequest.onsuccess 中进行调用,否则报错。
You can only call createObjectStore or deleteObjectStore when you are in a versionchange transaction, which rougly corresponds to the upgradeneeded event handler.
IDBTransaction 对象
- 数据操作 作为一个术语,用来描述对数据表数据的所有操作(读取、修改、插入或更新数据)
- transaction,中文翻译过来是事务、办理的意思。
- 数据库事务就是一个抽象单元,它包含了一次或多次对数据库的数据操作。
- 如果事务中的任何一部分数据操作失败了,则事务的所有操作都会撤销,数据库会恢复到事务之前的状态
数据所有操作(读取、修改、插入或删除)均在 transactions 中完成。
-
属性
- IDBTransaction.db: 返回当前对连接的数据库的引用(返回一个 IDBDatabase 对象)
- IDBTransaction.mode: 返回当前操作的权限
- IDBTransaction.error: 在 transaction 不成功时返回的错误消息
-
事件
- IDBTransaction.oncomplete: 在 transaction 全部完成时触发
-
IDBTransaction.abort(): 放弃本次连接的 transaction 的所有操作
- IDBTransaction.objectStore(name): 获取指定名称的对象存储空间
- 该方法返回一个 IDBObjectStore 对象
IDBObjectStore 对象
由于这个对象的实例方法有点多,下面只列出部分,详细的请查阅 MDN
- IDBObjectStore.add(value[,key]): 添加数据
- value:存储的数据
- key:用来识别数据的键
- 该方法返回一个 IDBRequest 对象
- 可以用 success 事件来监听是否添加数据成功
- IDBObjectStore.clear(): 清除数据
麻蛋,太多了,不想继续写了,以后用到再来补充吧~
IDBRequest 对象
成功向 IndexedDB 添加数据的一个例子
这里只写了为数据库添加数据的代码,没有写查询数据、删除数据的操作。
// 全局变量,用来引用数据库
let database;
// 向指定的数据库发出连接请求
let DBOpenRequest = window.indexedDB.open('firstDB', 4.0);
// 在请求的数据库版本不可用时触发,比如数据库不存在
DBOpenRequest.onupgradeneeded = function(event) {
console.log('upgradeneeded happens~');
// 得到对数据库的引用
database = event.target.result;
// 为数据库添加 2 个对象存储空间
database.createObjectStore('person store', {
keyPath: 'objKey'
});
database.createObjectStore('animal store', {
keyPath: 'objKey'
});
};
DBOpenRequest.onsuccess = function(event) {
console.log('连接数据库成功~');
// 得到对数据库的引用
database = event.target.result;
// 创建一个事务
// 下面函数第一个参数是需要被引入这个事务的对象存储空间的名称
let transaction = database.transaction(['person store', 'animal store'], 'readwrite');
// 获取指定的对象存储空间的引用
let personStore = transaction.objectStore('person store');
// 新建3个测试对象
let user1 = {
objKey: 11111,
name: 'percy',
age: 22,
skills: ['html', 'css', 'js']
};
let user2 = {
objKey: 22222,
name: 'jake',
age: 30,
skills: {
python: 'master',
javascript: 'master',
java: 'know a little'
}
};
let user3 = {
objKey: 33333,
name: 'alice',
age: 18,
skills: 'I have beautiful face. Lol...'
};
// 为指定的对象存储空间添加数据
// 这里使用 put 方法添加数据,注意 add 和 put 方法的不同
// 可以使用互换下面语句试试看
// let DBRequest = personStore.add(data);
let DBRequest = personStore.put(user1);
// 为了节省代码,就不为下面的两个对象添加检错机制了
personStore.put(user2);
personStore.put(user3);
// 监听写入数据时是否出错
DBRequest.onerror = function(event) {
console.log('为 person store 写入数据出错~' + event.target.error);
};
// 监听数据是否写入成功
DBRequest.onsuccess = function() {
console.log('为 person store 添加数据成功~');
};
};
DBOpenRequest.onblocked = function(event) {
console.log('blocked happens~');
};
DBOpenRequest.onerror = function(event) {
console.log('获取数据库时发生错误:' + event.target.error);
};
实际应用
- 创建自给自足的离线应用
- 优化性能,将部分频繁使用的服务器数据保存到本地的 IndexedDB 数据库中(超级定制缓存)
- 改进本地存储(localStorage、sessionStorage),用 IndexedDB 来存储比较大的数据
本文对你有帮助?欢迎扫码加入前端学习小组微信群: