# 怎么使用IndexedDB
## 一、IndexedDB概述
### 1.1 什么是IndexedDB
IndexedDB是一種在瀏覽器中存儲大量結構化數據的底層API。它是Web Storage API(如localStorage)的更強大替代方案,具有以下關鍵特性:
- **非關系型數據庫**:基于鍵值對存儲,而非傳統的關系型表格
- **異步操作**:所有操作都是異步的,不會阻塞UI線程
- **支持事務**:提供ACID事務保證
- **大容量存儲**:通常允許存儲比localStorage大得多的數據(通常為50MB+)
- **索引支持**:可以創建索引實現高效查詢
- **同源策略**:遵循同源策略,不同網站無法訪問彼此的數據
### 1.2 適用場景
IndexedDB特別適合以下場景:
- 需要離線工作的Web應用
- 需要存儲大量結構化數據的應用
- 需要復雜查詢的應用
- 需要存儲二進制數據(如圖片、文件)的應用
## 二、基本概念
### 2.1 核心組件
1. **數據庫(Database)**:頂層的容器,每個源可以創建多個數據庫
2. **對象存儲(Object Store)**:相當于關系型數據庫中的表
3. **索引(Index)**:提供對對象存儲中數據的快速查找
4. **事務(Transaction)**:所有操作必須在事務中執行
5. **游標(Cursor)**:用于遍歷對象存儲或索引中的記錄
6. **鍵(Key)**:每條記錄的唯一標識符
### 2.2 數據模型
IndexedDB使用鍵值對存儲數據,其中:
- **鍵(Key)**:可以是數字、字符串、日期、數組或二進制數據
- **值(Value)**:可以是任何JavaScript對象,包括復雜對象和二進制數據
## 三、基本操作指南
### 3.1 打開/創建數據庫
```javascript
const request = indexedDB.open('myDatabase', 1);
request.onerror = (event) => {
console.error('數據庫打開失敗:', event.target.error);
};
request.onsuccess = (event) => {
const db = event.target.result;
console.log('數據庫打開成功');
// 在這里執行數據庫操作
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 在這里創建或修改對象存儲
if (!db.objectStoreNames.contains('customers')) {
const store = db.createObjectStore('customers', { keyPath: 'id' });
// 創建索引
store.createIndex('name', 'name', { unique: false });
store.createIndex('email', 'email', { unique: true });
}
};
function addCustomer(db, customer) {
const transaction = db.transaction(['customers'], 'readwrite');
const store = transaction.objectStore('customers');
const request = store.add(customer);
request.onsuccess = () => {
console.log('客戶添加成功');
};
request.onerror = (event) => {
console.error('添加客戶失敗:', event.target.error);
};
}
function getCustomer(db, id) {
const transaction = db.transaction(['customers'], 'readonly');
const store = transaction.objectStore('customers');
const request = store.get(id);
request.onsuccess = () => {
if (request.result) {
console.log('找到客戶:', request.result);
} else {
console.log('未找到該客戶');
}
};
request.onerror = (event) => {
console.error('查詢失敗:', event.target.error);
};
}
function getCustomerByName(db, name) {
const transaction = db.transaction(['customers'], 'readonly');
const store = transaction.objectStore('customers');
const index = store.index('name');
const request = index.get(name);
request.onsuccess = () => {
if (request.result) {
console.log('找到客戶:', request.result);
} else {
console.log('未找到該客戶');
}
};
}
function updateCustomer(db, customer) {
const transaction = db.transaction(['customers'], 'readwrite');
const store = transaction.objectStore('customers');
const request = store.put(customer);
request.onsuccess = () => {
console.log('客戶信息更新成功');
};
request.onerror = (event) => {
console.error('更新失敗:', event.target.error);
};
}
function deleteCustomer(db, id) {
const transaction = db.transaction(['customers'], 'readwrite');
const store = transaction.objectStore('customers');
const request = store.delete(id);
request.onsuccess = () => {
console.log('客戶刪除成功');
};
request.onerror = (event) => {
console.error('刪除失敗:', event.target.error);
};
}
function getAllCustomers(db) {
const transaction = db.transaction(['customers'], 'readonly');
const store = transaction.objectStore('customers');
const customers = [];
store.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
customers.push(cursor.value);
cursor.continue();
} else {
console.log('所有客戶:', customers);
}
};
}
function getCustomersByAgeRange(db, min, max) {
const transaction = db.transaction(['customers'], 'readonly');
const store = transaction.objectStore('customers');
const index = store.index('age');
const range = IDBKeyRange.bound(min, max);
const customers = [];
index.openCursor(range).onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
customers.push(cursor.value);
cursor.continue();
} else {
console.log('年齡范圍內的客戶:', customers);
}
};
}
function batchAddCustomers(db, customers) {
const transaction = db.transaction(['customers'], 'readwrite');
const store = transaction.objectStore('customers');
customers.forEach(customer => {
store.add(customer);
});
transaction.oncomplete = () => {
console.log('批量添加完成');
};
transaction.onerror = (event) => {
console.error('批量添加失敗:', event.target.error);
};
}
function handleDBError(error) {
console.error('數據庫錯誤:', error);
// 可以在這里實現錯誤恢復或用戶通知
}
// 在所有請求中添加錯誤處理
request.onerror = (event) => handleDBError(event.target.error);
const DB_VERSION = 2;
const request = indexedDB.open('myDatabase', DB_VERSION);
request.onupgradeneeded = (event) => {
const db = event.target.result;
const oldVersion = event.oldVersion;
if (oldVersion < 1) {
// 初始版本創建
db.createObjectStore('customers', { keyPath: 'id' });
}
if (oldVersion < 2) {
// 版本2升級
const transaction = event.target.transaction;
const store = transaction.objectStore('customers');
store.createIndex('registrationDate', 'registrationDate');
}
};
if (!window.indexedDB) {
console.log('您的瀏覽器不支持IndexedDB');
// 提供備用方案
}
navigator.storage.estimate().then(estimate => {
console.log(`已使用: ${estimate.usage} bytes`);
console.log(`剩余: ${estimate.quota - estimate.usage} bytes`);
});
navigator.storage.persist().then(granted => {
if (granted) {
console.log('存儲將不會被自動清理');
}
});
class NotesDB {
constructor() {
this.db = null;
this.init();
}
init() {
const request = indexedDB.open('NotesDB', 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains('notes')) {
const store = db.createObjectStore('notes', {
keyPath: 'id',
autoIncrement: true
});
store.createIndex('title', 'title', { unique: false });
store.createIndex('createdAt', 'createdAt', { unique: false });
}
};
request.onsuccess = (event) => {
this.db = event.target.result;
console.log('數據庫初始化完成');
};
request.onerror = (event) => {
console.error('數據庫初始化失敗:', event.target.error);
};
}
// 其他方法:addNote, getNote, getAllNotes, updateNote, deleteNote等
}
function cacheFile(db, file) {
return new Promise((resolve, reject) => {
const transaction = db.transaction(['files'], 'readwrite');
const store = transaction.objectStore('files');
const reader = new FileReader();
reader.onload = (event) => {
const request = store.put({
id: file.name,
name: file.name,
type: file.type,
size: file.size,
lastModified: file.lastModified,
data: event.target.result
});
request.onsuccess = () => resolve();
request.onerror = (event) => reject(event.target.error);
};
reader.readAsArrayBuffer(file);
});
}
IndexedDB為Web應用提供了強大的客戶端存儲能力,適合需要存儲大量結構化數據的場景。掌握IndexedDB需要理解其核心概念和異步編程模型。通過合理設計數據庫結構、正確使用事務和索引,可以構建出性能優異的離線應用。
隨著PWA(Progressive Web Apps)的普及,IndexedDB的重要性日益增加,成為現代Web開發中不可或缺的技術之一。 “`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。