JavaScript - IndexedDB



什么是 IndexedDB?

IndexedDB,或索引数据库,是一个低级的 JavaScript API。其功能包括存储和检索大量结构化数据,包括文件和 Blob。它能够与客户端数据库交互,使 Web 应用程序能够在用户的设备上本地存储、查询和修改数据。此功能在构建处理大量数据、脱机工作以及通过本地数据缓存提供响应式用户体验的 Web 应用程序时尤其有用。

IndexedDB 的关键概念和特性

  • 异步 API − IndexedDB 使用异步 API,依赖于事件驱动的编程,以防止主线程阻塞并增强用户体验。

  • 数据库 − IndexedDB 数据库充当对象存储的容器,便于数据的组织、检索和删除。

  • 对象存储 − 对象存储类似于关系数据库中的表,封装 JavaScript 对象的集合;它支持 CRUD 操作。

  • 索引 − 对象存储中的索引可以提高数据查询效率,因为它们能够根据特定字段提高搜索和排序性能。

  • 事务 − IndexedDB 中的事务执行所有操作,通过使多个操作作为一个单元成功或失败来保证一致性和完整性。

为什么要使用 IndexedDB?

Web 开发人员在寻找高效的客户端存储解决方案时,发现 IndexedDB 不可或缺。它的异步特性保证了响应式的用户体验:它避免了主线程阻塞;此外,它对事务的支持通过维护数据完整性值得称赞。IndexedDB 能够本地管理大量结构化数据;此功能大大增强了脱机功能,减少了对持续服务器通信的需求。凭借其灵活的键结构、对优化查询的索引支持以及升级模式的能力,它是构建需要本地存储、脱机支持和高效数据管理的 Web 应用程序的强大选择。

CRUD 操作

现在让我们看看 IndexedDB 的 CRUD 操作代码。

创建/插入操作

要在对象存储中插入新记录,可以使用 IndexedDB 中的 add() 方法。此方法接受 JavaScript 对象或值作为参数,然后将其添加到指定的对象存储中。但是,如果已经存在具有相同键参数的条目,则此操作将失败,因此它非常适合保证唯一性。

const request = objectStore.add(data);
request.onsuccess = () => {
// Handle success event
};

request.onerror = () => {
// Handle error
};

读取 (检索) 操作

get() 方法

使用 get() 方法:它从对象存储中检索单个记录,此操作取决于您是否知道目标条目的特定键。

openCursor() 方法

启动一个主动游标来迭代对象存储中的记录,openCursor() 方法通过允许处理每个单独的条目来提高效率和控制;这在遍历对象存储中存在的全部条目时非常有用。

const request = objectStore.openCursor();
request.onsuccess = (event) => {
   const cursor = event.target.result;
   if (cursor) {
      const data = cursor.value;
      // Process data
      cursor.continue();
   }
};

request.onerror = () => {
   // Handle error
};

更新操作

put() 方法更新现有记录,或者在键不存在时添加新记录。它的多功能性使其适合于数据操作,特别是更新和插入。

const request = objectStore.put(data);

删除操作

要根据其键从对象存储中删除特定记录,必须使用 delete() 方法;此方法提供了一种直接删除条目的方法。

const request = objectStore.delete(key);

实现示例

上述所有重要的 CRUD 操作方法都在此代码中实现。它将数据库数据显示为表格,每条记录都带有删除和更新按钮。单击创建按钮时,它会在屏幕上显示一个用于表单创建的元素;从而允许输入姓名和电子邮件以插入到数据库中。默认情况下,此表单隐藏;它只在单击按钮后出现,并在其任务完成后消失。'prompt()' 方法填充了详细信息更新表单,此功能为用户提供了便利,因为警报也出现在同一位置。此外:相关的警报用于向用户发出成功事件或错误的信号。

<!DOCTYPE html>
<html>
<head>
   <style>
      body {
         font-family: Arial, sans-serif;
         margin: 20px;
      }
      h2 {
         color: #333;
      }

      button {
         padding: 8px;
         margin: 5px;
      }

      #createForm, #updateForm {
         display: none;
         border: 1px solid #ddd;
         padding: 10px;
         margin-bottom: 10px;
      }

      table {
         border-collapse: collapse;
         width: 100%;
         margin-top: 20px;
         width: auto;
      }

      th, td {
         border: 1px solid #dddddd;
         text-align: left;
         padding: 8px;
      }

      th {
         background-color: #f2f2f2;
      }
   </style>
</head>
<body>
   <h2>IndexedDB CRUD Operations</h2>
   <button onclick="showCreateForm()">Create Data</button>
   <div id="createForm" style="display: none;">
      // hidden by default, displayed on create button click
      <h3>Create Data</h3>
      <label for="name">Name:</label>
      <input type="text" id="name" required><br><br>
      <label for="email">Email:</label>
      <input type="email" id="email" required><br>
      <button onclick="createData()">Save</button>
      <button onclick="cancelCreate()">Cancel</button>
   </div>
   <table id="data-table">
      <thead>
         <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Email</th>
            <th>Actions</th>
         </tr>
      </thead>
      <tbody></tbody>
   </table>
   <script>
      const dbName = "myDatabase";
      let db;
	   // Open/create indexedDB named myDatabase with version 11
      const request = window.indexedDB.open(dbName, 11);
      request.onerror = (event) => {
         alert("Database error: " + event.target.errorCode);
      };

      request.onsuccess = (event) => {
         db = event.target.result;
         showData();
      };
      request.onupgradeneeded = (event) => {
         db = event.target.result;
         const objectStore = db.createObjectStore("myObjectStore", { keyPath: "id", autoIncrement: true });
         objectStore.createIndex("name", "name", { unique: false });
         objectStore.createIndex("email", "email", { unique: true });
      };
      function showData() {
         //populates the table from the db
         const transaction = db.transaction(["myObjectStore"], "readonly");
         const objectStore = transaction.objectStore("myObjectStore");
         const tableBody = document.querySelector("#data-table tbody");
         tableBody.innerHTML = "";
         const request = objectStore.openCursor();
         request.onsuccess = (event) => {
            const cursor = event.target.result;
            if (cursor) {
               const row = tableBody.insertRow();
               row.insertCell(0).textContent = cursor.value.id;
               row.insertCell(1).textContent = cursor.value.name;
               row.insertCell(2).textContent = cursor.value.email;
               const actionsCell = row.insertCell(3);
               //update & delete is performed on the basis of id, hence id is passed as parameter to functions when corresponding button is clicked
               actionsCell.innerHTML = `
               <button onclick="showUpdateForm(${cursor.value.id})">Update</button>
               <button onclick="deleteData(${cursor.value.id})">Delete</button>
                    `;
               cursor.continue();
            }
         };
      }

      function createData() {
         const transaction = db.transaction(["myObjectStore"], "readwrite");
         const objectStore = transaction.objectStore("myObjectStore");
         const name = document.getElementById("name").value;
         const email = document.getElementById("email").value;

         const newData = {
            name: name,
            email: email
         };

         const request = objectStore.add(newData);

         request.onsuccess = () => {
            showData();
            cancelCreate();
            alert("Data added successfully")
         };

         request.onerror = () => {
            alert("Error creating data.");
         };
      }

      function showCreateForm() {
         document.getElementById("createForm").style.display = "block";
      }

      function cancelCreate() {
      //if the user decides to not insert the record.
      document.getElementById("createForm").style.display = "none";
         document.getElementById("name").value = "";
         document.getElementById("email").value = "";
      }

      function showUpdateForm(id) {
         const transaction = db.transaction(["myObjectStore"], "readwrite");
         const objectStore = transaction.objectStore("myObjectStore");

         const request = objectStore.get(id);

         request.onsuccess = (event) => {
            const data = event.target.result;
 
            if (data) {
               const name = prompt("Update Name:", data.name);
               const email = prompt("Update Email:", data.email);

               if (name !== null && email !== null) {
                  data.name = name;
                  data.email = email;

                  const updateRequest = objectStore.put(data);

                  updateRequest.onsuccess = () => {
                     showData();
                     alert("Updated data for "+data.name)
                  };

                  updateRequest.onerror = () => {
                     alert("Error updating data.");
                  };
               }
            }
         };
      }

      function deleteData(id) {
         const transaction = db.transaction(["myObjectStore"], "readwrite");
         const objectStore = transaction.objectStore("myObjectStore");
 
         const request = objectStore.delete(id);
 
         request.onsuccess = () => {
            showData();
            alert("Deleted data for id "+id)
         };

         request.onerror = () => {
            alert("Error deleting data.");
         };
      }
     
   </script>
</body>
</html>

尝试运行上述程序。在输出中,您将获得一个创建、更新和删除数据的界面。新创建或更新的数据将在操作完成后立即以表格形式出现。

广告
© . All rights reserved.