操作全是异步
开启数据库
indexedDB.open()
为开启的API,还可以为开启的数据库设置版本号
// 打开数据库
let request, database;
request = indexedDB.open('test');
request.onerror = function (event) {
console.log(event);
}
request.onsuccess = function (event) {
console.log(event);
database = event.target.result;
// 设置版本号
if (database.version != '1.0') {
request = database.setVersion('1.0');
request.onerror = function (event) {
console.log(`错误码${event.target.errorCode}`);
}
request.onsuccess = function (event) {
console.log(`已经设置数据库${database.name}的版本为${database.version}`);
}
} else {
console.log(`数据库${database.name}的版本号为${database.version}`);
}
}
数据库第一次开启后,关闭浏览器再次打开调用open
,则相当于连接该数据库。
数据库“建表”,插入store
插入indexedDB
中的对象,类似于MySQL
中的建表操作,需要建立好数据库才能调用,API为database.createObjectStore("books", {keyPath: "isbn"})
,注意,该方法只能在open
的回调中的onupgradeneeded
的方法中使用
一个版本建立多个存储空间
一个版本创建多个存储空间,只能在一次数据库更新或者创建的时候,在onupgradeneeded
中一次性创建多个。
// 来自w3c的例子
// 这里用createIndex来创建不同的keypath的存储空间
const request = indexedDB.open("library");
let db;
request.onupgradeneeded = function() {
// The database did not previously exist, so create object stores and indexes.
const db = request.result;
const store = db.createObjectStore("books", {keyPath: "isbn"});
const titleIndex = store.createIndex("by_title", "title", {unique: true});
const authorIndex = store.createIndex("by_author", "author");
// Populate with initial data.
store.put({title: "Quarry Memories", author: "Fred", isbn: 123456});
store.put({title: "Water Buffaloes", author: "Fred", isbn: 234567});
store.put({title: "Bedrock Nights", author: "Barney", isbn: 345678});
};
request.onsuccess = function() {
db = request.result;
};
更新数据库
用indexedDB.open(database, version)
的第二个参数去升级数据库版本,注意version
只能大于等于最新版本,等于时触发onsuccess
,大于时依次触发onupgradeneeded
、onsuccess
方法,另外需要注意的时,version
不能是浮点数,否则2.4 => 2
不会触发onupgradeneeded
方法
事务
indexedDB.transaction
在open
中的回调onsuccess
和onupgradeneeded
中都可以使用,都用来增删改查数据库中存储空间的数据
对数据的操作
let db = request.result;
let transaction = db.transaction('books2', 'readwrite');
let store = transaction.objectStore('books2');
//let addRequest1 = store.add({
// author: 'lalala2',
// title: '测试用的2',
// isbn: 324552
//});
//addRequest1.onerror = function(e){
// console.log('失败', e);
//}
//addRequest1.onsuccess = function(e){
// console.log('成功', e);
//}
let addRequest = store.add({
author: 'lalala',
title: '测试用的1',
isbn: 334552
});
let addRequest = store.add({
author: 'lalala',
title: '测试用的1',
isbn: 334552
});
addRequest.onerror = function(e){
console.log(e);
}
addRequest.onsuccess = function(e){
let getAdd = store.get(e.target.result);
getAdd.onsuccess = function(e){
console.log(e);
}
getAdd.onerror = function(e){
console.log(e);
}
}
//let addRequest2 = store.add({
// author: 'lalala1',
// title: '测试用的1',
// isbn: 314552
//});
//addRequest2.onerror = function(e){
// console.log('失败', e);
//}
//addRequest2.onsuccess = function(e){
// console.log('成功', e);
//}
let deleteData = store.delete(234567);
deleteData.onsuccess = function(e){
console.log('删除', e);
}
- 事务是异步的
- 修改、删除、增加的数据在控制台不会即时刷新,但是可以获取到
- 如果在同一个事务中,增删改查的操作有一个失败了,那么其后的操作都会失败,例如上述的代码,如果先添加数据,再添加注释的数据,则后面的注释数据则会添加失败。
-
get
获取数据后,可以在其中修改,再put
,例子可以看mdn上
游标
可以理解为Object.keys()
这个方法,只不过openCursor
接受的两个参数让遍历整个存储空间更方便。
- 第一个参数
IDKeyRange
- 第二个参数
next
、prev
、nextunique
、prevunique
(后面两个用于游标查询的数据可能不止一条情况,只会返回键值最小的,但是在IDKeyRange
用创建存储空间的keypath
时,基本不会出现一个键值索引到多条数据的情况)用于遍历顺序
// 这里是选取不同keypath的存储空间,可以配合IDKeyRange来指定唯一键值
const tx = db.transaction("books", "readonly");
const store = tx.objectStore("books");
const index = store.index("by_author");
let keyRange = IDBKeyRange.bound("Barney", "Fred", false, true);
index.openCursor(keyRange, 'next').onsuccess = function(e){
console.log(e);
let cursor = e.target.result;
if(cursor){
console.log('存在游标', `name: ${cursor.value.author},title: ${cursor.value.title}`);
cursor.continue();
} else {
console.log('游标失败');
}
};
另外,各种IDKeyRange
的API可以去mdn
查询
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。