Skip to content

IndexedDB - 连接

数据库是存储和检索结构化数据的基本组件。要与 IndexedDB 数据库中的数据进行交互,我们必须首先建立连接。本章将介绍使用现代 JavaScript 实践创建、打开、版本化和删除数据库的基本操作。

在 IndexedDB 中,你可以使用 indexedDB.open() 方法创建新数据库或打开现有数据库。此方法是异步的,会立即返回一个 IDBOpenDBRequest 对象。操作的实际结果(成功或失败)通过事件传递。

const request = indexedDB.open(databaseName, version);
  • databaseName: 一个字符串,表示数据库的名称。
  • version: 一个可选的正整数。此版本号对于管理数据库模式(schema)更改至关重要。如果指定的版本高于数据库的当前版本,则会触发 upgradeneeded 事件。

此操作不会立即为你提供数据库连接。相反,你必须监听返回的 request 对象上的事件。

打开连接时,有三个关键事件需要处理:

  • onsuccess: 连接成功建立时触发。数据库连接对象通过 event.target.result 可用。
  • onerror: 连接尝试期间发生错误时触发(例如,磁盘配额超出、安全错误)。
  • onupgradeneeded: 仅当提供给 open() 的 version 号高于现有数据库的版本(或数据库尚不存在)时触发。这是你可以创建或删除对象存储(object store)和索引(index)的唯一地方。

这是一个如何打开数据库并设置其模式的现代化完整示例。此代码使用了现代 ES6 语法(let、const、箭头函数),并将消息记录到浏览器的控制台,这是开发中的最佳实践。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>IndexedDB Connection</title>
</head>
<body>
<h1>IndexedDB Connection Example</h1>
<div id="status">Initializing...</div>
<script>
const dbName = "MyNotesAppDB";
const dbVersion = 1;
const statusDiv = document.getElementById('status');
// All modern browsers support indexedDB globally.
if (!window.indexedDB) {
statusDiv.textContent = "Your browser doesn't support a stable version of IndexedDB.";
}
// Let's open our database
const request = indexedDB.open(dbName, dbVersion);
request.onerror = (event) => {
console.error(`Database error: ${event.target.error.message}`);
statusDiv.textContent = 'Error opening database.';
};
request.onsuccess = (event) => {
console.log('Database opened successfully.');
statusDiv.textContent = 'Database connection successful!';
// db 对象是数据库的连接
const db = event.target.result;
// 最佳实践是在操作完成后关闭连接
db.close();
};
request.onupgradeneeded = (event) => {
console.log('Database upgrade needed or database created.');
statusDiv.textContent = 'Setting up database schema...';
const db = event.target.result;
// 为我们的笔记创建一个对象存储
// 这类似于关系型数据库中的表
const objectStore = db.createObjectStore("notes", { keyPath: "id", autoIncrement: true });
// 创建一个索引以便按标题搜索笔记。索引允许快速搜索。
objectStore.createIndex("title", "title", { unique: false });
objectStore.createIndex("created_at", "created_at", { unique: false });
console.log('Object store and indexes created.');
};
</script>
</body>
</html>

你可以直接在浏览器的开发者工具中验证数据库的创建和结构:

  • 在浏览器中打开页面。
  • 右键单击并选择“检查”或按 F12 打开开发者工具。
  • 导航到“Application”选项卡。
  • 在左侧菜单中,找到“Storage”并展开“IndexedDB”部分。
  • 你将看到你的数据库“MyNotesAppDB”。展开它将显示“notes”对象存储及其索引。

要完全删除一个数据库,请使用 indexedDB.deleteDatabase() 方法。这也是一个异步操作。

const deleteRequest = indexedDB.deleteDatabase(dbName);

一个常见的问题是在数据库有打开连接时尝试删除它。在浏览器删除数据库之前,你必须关闭数据库的所有连接。

// 在运行此代码之前,请确保“MyNotesAppDB”的所有连接都已关闭。
const dbName = "MyNotesAppDB";
const deleteRequest = indexedDB.deleteDatabase(dbName);
deleteRequest.onsuccess = () => {
console.log(`Database '${dbName}' deleted successfully.`);
};
deleteRequest.onerror = (event) => {
console.error(`Error deleting database: ${event.target.error.message}`);
};
// 如果删除操作被打开的连接阻塞,则会触发此事件。
deleteRequest.onblocked = () => {
console.warn('Database deletion blocked. Please close all open connections.');
};

尽管浏览器会自动管理连接生命周期,但最佳实践是在不再需要数据库连接时(尤其是在删除操作之前)显式关闭它。你可以在成功连接后获得的数据库对象上调用 close() 方法。

request.onsuccess = (event) => {
const db = event.target.result;
// ... 执行操作 ...
db.close();
};