IndexedDB数据库应用
IndexedDB 是一个在浏览器中持久化数据的大型、结构化存储系统。与 LocalStorage 相比,它允许存储更大量的结构化数据。同时,IndexedDB 所有的操作都是异步的,这样在处理大量数据时,用户界面不会冻结。
IndexedDB中添加新的数据
// 打开(或创建)数据库
let openRequest = indexedDB.open("myDatabase", 1);
openRequest.onupgradeneeded = function(e) {
// 当数据库首次创建或版本变更时调用
let db = e.target.result;
// 创建一个名为 "books" 的对象储存空间(Object Store)
if (!db.objectStoreNames.contains('books')) {
let storeOject = db.createObjectStore('books', {keyPath: 'isbn'});
// 创建一个用于搜索的索引
storeOject.createIndex('by_author', 'author');
}
};
openRequest.onerror = function(e) {
// 如果打开数据库失败,处理错误
console.log(e);
};
openRequest.onsuccess = function(e) {
// 如果数据库打开成功
let db = e.target.result;
console.log('DB loaded');
// 添加数据
let tx = db.transaction('books', 'readwrite');
let store = tx.objectStore('books');
let item = {
title: "JavaScript for Beginners",
author: "John Doe",
isbn: 123456,
created: Date.now()
};
let request = store.add(item);
request.onsuccess = function(e) {
// 获取数据
let getJohnBooks = store.index('by_author').getAll('John Doe');
getJohnBooks.onsuccess = function(e) {
console.log('Books by John Doe:', e.target.result);
}
}
};
在上述代码中:
-
indexedDB.open(“myDatabase”, 1); - 创建(或打开)名为 “myDatabase” 的数据库并设置版本为 1。
-
在onupgradeneeded事件中,我们创建一个名为 books 的对象存储空间。每一个对象存储空间在数据库中都代表一类数据实体(如:用户,订单,商品等),类似于关系型数据库中的表。
-
在 books 存储空间下,我们还创建了一个名为 by_author 的索引。索引用于优化数据的搜索性能,与关系型数据库中的索引一样。
-
在 onsuccess 事件中,我们开启了一个读写事务并在 books 存储空间中添加了一本书的数据。
-
添加数据成功后,我们又通过 by_author 索引获取到了所有 John Doe 写的书。
IndexedDB中删除已存在的数据
在IndexedDB中,我们可以使用delete方法来删除已存在的数据。以下是一个示例:
// 打开数据库
let openRequest = indexedDB.open("myDatabase", 1);
openRequest.onupgradeneeded = function(e) {
let db = e.target.result;
if (!db.objectStoreNames.contains('books')) {
db.createObjectStore('books', {keyPath: 'isbn'});
}
};
openRequest.onsuccess = function(e) {
let db = e.target.result;
// 开启一个新的事务
let transaction = db.transaction('books', 'readwrite');
// 选定事务要使用的对象存储空间
let books = transaction.objectStore('books');
// 删除指定的数据
let isbn = 111111; // 这是之前添加的书籍的ISBN
let request = books.delete(isbn);
request.onsuccess = function() {
console.log(Book with isbn ${isbn} has been deleted);
};
request.onerror = function() {
console.log('Something goes wrong: ', request.error);
};
};
openRequest.onerror = function(e) {
console.log('Error occurred: ', e.target.error);
};
在这个示例中,我们首先打开了数据库,并开始了一个新的读写事务。然后我们选择了要操作的对象存储空间books。之后用delete方法删除了指定的书籍,传入的参数是我们想要删除的书籍的ISBN。这个删除操作是异步的,因此我们通过监听onsuccess和onerror事件来知道删除操作是否成功。
在IndexedDB中批量更新数据
在IndexedDB中,我们可以使用put方法来执行批量更新。put方法既可以插入新记录,也可以更新已存在的记录。若指定的键已存在,则更新该键对应的记录;若键不存在,则插入新记录。
以下是一个批量更新数据的示例:
// 打开数据库
let openRequest = indexedDB.open("myDatabase", 1);
openRequest.onupgradeneeded = function(e) {
let db = e.target.result;
if (!db.objectStoreNames.contains('books')) {
db.createObjectStore('books', {keyPath: 'isbn'});
}
};
openRequest.onsuccess = function(e) {
let db = e.target.result;
// 开始新的事务
let transaction = db.transaction('books', 'readwrite');
// 选择要操作的对象存储区
let books = transaction.objectStore('books');
// 待更新的书籍列表
let bookList = [
{isbn: 111111, title: "New Book Title 1", author: "New Author 1"},
{isbn: 222222, title: "New Book Title 2", author: "New Author 2"},
{isbn: 333333, title: "New Book Title 3", author: "New Author 3"}
];
// 批量更新数据
for (let book of bookList) {
let request = books.put(book);
request.onerror = function() {
console.log('Error occurred:', request.error);
};
}
transaction.oncomplete = function() {
console.log('Transaction completed: database modification finished.');
};
transaction.onerror = function() {
console.log('Transaction not opened due to error. Duplicate items not allowed.');
};
};
openRequest.onerror = function(e) {
console.log('Error occurred: ', e.target.error);
};
在此示例中,我们首先打开数据库,并开始新的读写事务。然后选择了要操作的对象存储空间books,并使用put方法将新的书籍信息添加或更新到仓库中。此操作是异步的,并为每个操作和整个事务的oncomplete和onerror事件添加了处理程序,以便在操作成功或失败时执行适当的操作。
IndexedDB中获取所有已存储的数据
在 IndexedDB 中,你可以使用openCursor方法来遍历并获取所有存储在一个对象存储空间(Object Store)中的数据。以下是一个示例:
// 打开数据库
let openRequest = indexedDB.open("myDatabase", 1);
openRequest.onupgradeneeded = function(e) {
let db = e.target.result;
if (!db.objectStoreNames.contains('books')) {
db.createObjectStore('books', {keyPath: 'isbn'});
}
};
openRequest.onsuccess = function(e) {
let db = e.target.result;
// 开启一个新的事务
let transaction = db.transaction('books', 'readonly');
// 选定事务要使用的对象存储空间
let books = transaction.objectStore('books');
// 打开游标来获取所有的数据
let request = books.openCursor();
request.onsuccess = function() {
let cursor = request.result;
if(cursor) {
console.log('ISBN: ' + cursor.key + ', Title: ' + cursor.value.title + ', Author: ' + cursor.value.author);
cursor.continue();
} else {
console.log('No more entries!');
}
};
};
openRequest.onerror = function(e) {
console.log('Error occurred: ', e.target.error);
};
在这个示例中,我们首先打开数据库,并开始了一个新的只读事务。然后,我们选择了要操作的对象存储空间books。然后,我们使用了openCursor方法来打开游标。游标可以用来遍历对象存储空间中的所有记录。我们在游标成功打开后的回调函数中打印出了每条记录的信息,并调用了游标的continue方法,这样就可以继续遍历下一条记录。当所有的记录都遍历完了,cursor对象就会变成null,这样我们就知道所有的记录已经遍历完了。
在IndexedDB中处理查询结果的异步性
在 IndexedDB 中,所有的 I/O 操作都是异步的,这意味着这些操作不会立即完成,而是在后台运行,这使得我们可以在等待这些操作完成的同时继续执行其他代码。
在 Javascript 中,我们可以使用 Promise 或者 async/await 来处理异步操作。对于 IndexedDB,虽然其原生 API 并不返回 Promise,但我们可以自己创建 Promise 来处理 IndexedDB 的异步性。
以下是一个使用 Promise 来获取 IndexedDB 中所有数据的示例:
function getAllData(dbName, storeName) {
return new Promise((resolve, reject) => {
let openRequest = indexedDB.open(dbName);
openRequest.onsuccess = function(e) {
let db = e.target.result;
let transaction = db.transaction(storeName, 'readonly');
let store = transaction.objectStore(storeName);
let request = store.getAll();
request.onsuccess = function() {
resolve(request.result);
};
request.onerror = function() {
reject(request.error);
};
};
openRequest.onerror = function(e) {
reject(e.target.error);
};
});
}
然后你可以通过以下方式来调用这个函数并处理结果:
getAllData("myDatabase","books")
.then(data => {
// 在这里处理数据
console.log(data);
})
.catch(error => {
// 在这里处理错误
console.error('Error occurred: ', error);
});
另外,你也可以使用第三方库,如 idb,Dexie.js 等,这些库为 IndexedDB 提供了返回 Promise 的 API,使得处理异步操作更加方便。
以上就是文章全部内容了,如果喜欢这篇文章的话,还希望三连支持一下,感谢!
更多推荐
所有评论(0)