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

在上述代码中:

  1. indexedDB.open(“myDatabase”, 1); - 创建(或打开)名为 “myDatabase” 的数据库并设置版本为 1。

  2. 在onupgradeneeded事件中,我们创建一个名为 books 的对象存储空间。每一个对象存储空间在数据库中都代表一类数据实体(如:用户,订单,商品等),类似于关系型数据库中的表。

  3. 在 books 存储空间下,我们还创建了一个名为 by_author 的索引。索引用于优化数据的搜索性能,与关系型数据库中的索引一样。

  4. 在 onsuccess 事件中,我们开启了一个读写事务并在 books 存储空间中添加了一本书的数据。

  5. 添加数据成功后,我们又通过 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,使得处理异步操作更加方便。

以上就是文章全部内容了,如果喜欢这篇文章的话,还希望三连支持一下,感谢!

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐