IndexedDB简介
IndexedDB
是浏览器提供的一种本地存储解决方案,用于存储大量的结构化数据。它支持异步操作,允许你存储对象、数组、甚至是二进制数据,并为它们提供索引以提高查询效率。它的设计目的是用于处理大规模数据存储,适合离线应用和大数据处理。
IndexedDB的特点
- 存储大数据:相比于
localStorage
,IndexedDB
支持存储大量数据(通常是几十MB甚至GB级别)。 - 异步操作:
IndexedDB
是异步的,避免了阻塞UI线程。 - 对象存储:可以存储 JavaScript 对象,而不仅仅是字符串(
localStorage
只能存储字符串)。 - 事务支持:
IndexedDB
支持事务,可以确保操作的原子性。 - 支持索引:通过创建索引,可以提高数据查询的效率。
如何使用IndexedDB
IndexedDB
是通过 JavaScript 的 indexedDB
对象进行操作的。以下是一个简单的使用流程,包括如何打开数据库、添加数据、读取数据、删除数据等。
1. 打开数据库 (indexedDB.open
)
使用 indexedDB.open()
打开数据库或创建一个新的数据库。如果数据库不存在,它会创建一个新的数据库;如果数据库已存在,则使用现有的数据库。
const request = indexedDB.open('myDatabase', 1); // 打开或创建数据库,版本号为1
-
参数:
- 'myDatabase':数据库的名称。
- 1:数据库的版本号。每次数据库结构变化时,需要增大版本号。
-
事件:
- onupgradeneeded:当数据库创建或版本升级时触发,用来创建对象存储区(object store)和索引。
- onsuccess:当数据库打开成功时触发。
- onerror:当打开数据库失败时触发。
const request = indexedDB.open('myDatabase', 1);
// 处理数据库版本升级,创建对象存储区
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains('myStore')) {
const store = db.createObjectStore('myStore', { keyPath: 'id' }); // 创建对象存储区
store.createIndex('name', 'name', { unique: false }); // 创建索引
}
};
// 数据库打开成功
request.onsuccess = (event) => {
const db = event.target.result;
console.log('数据库打开成功');
};
// 打开数据库失败
request.onerror = (event) => {
console.error('打开数据库失败', event.target.error);
};
2. 添加数据 (put
)
一旦数据库打开成功,你可以通过事务和对象存储区(object store)向数据库中添加数据。
const addData = (db, data) => {
const transaction = db.transaction('myStore', 'readwrite'); // 读写事务
const store = transaction.objectStore('myStore'); // 获取对象存储区
const request = store.put(data); // 添加或更新数据
request.onsuccess = () => {
console.log('数据存储成功');
};
request.onerror = (event) => {
console.error('数据存储失败', event.target.error);
};
};
- 事务:
db.transaction('storeName', 'readwrite')
创建一个事务。可以设置事务的权限为'readonly'
或'readwrite'
。 - put():如果数据的
key
已经存在,则会更新该数据;如果不存在,则会插入新数据。
3. 读取数据 (get
)
通过 get()
方法可以从对象存储区中获取数据。需要传入数据的主键(key)。
const getData = (db, key) => {
const transaction = db.transaction('myStore', 'readonly'); // 只读事务
const store = transaction.objectStore('myStore'); // 获取对象存储区
const request = store.get(key); // 根据主键获取数据
request.onsuccess = (event) => {
const result = event.target.result;
if (result) {
console.log('获取的数据:', result);
} else {
console.log('未找到该数据');
}
};
request.onerror = (event) => {
console.error('读取数据失败', event.target.error);
};
};
- get():根据主键
key
获取数据。如果数据存在,返回对应的数据;如果数据不存在,返回null
。
4. 删除数据 (delete
)
可以使用 delete()
方法删除指定主键的数据。
const removeData = (db, key) => {
const transaction = db.transaction('myStore', 'readwrite'); // 读写事务
const store = transaction.objectStore('myStore'); // 获取对象存储区
const request = store.delete(key); // 根据主键删除数据
request.onsuccess = () => {
console.log('数据删除成功');
};
request.onerror = (event) => {
console.error('删除数据失败', event.target.error);
};
};
- delete():根据指定的
key
删除数据。
5. 创建索引 (createIndex
)
IndexedDB
允许你为对象存储区创建索引,索引可以加速对数据的查询。可以通过 createIndex()
方法来创建索引。
const request = indexedDB.open('myDatabase', 2); // 升级到版本2
request.onupgradeneeded = (event) => {
const db = event.target.result;
const store = db.createObjectStore('myStore', { keyPath: 'id' });
store.createIndex('name', 'name', { unique: false }); // 创建索引
};
- createIndex():创建一个索引。参数包括索引名称、索引字段、是否唯一。
6. 事务和错误处理
IndexedDB
使用事务来确保操作的原子性。可以同时进行多个操作,事务会确保所有操作都成功,或者在出错时回滚。
const transaction = db.transaction('myStore', 'readwrite');
transaction.onerror = (event) => {
console.error('事务出错:', event.target.error);
};
const store = transaction.objectStore('myStore');
store.put({ id: 1, name: 'John' });
store.put({ id: 2, name: 'Jane' });
7. 列出所有数据
IndexedDB
提供了 openCursor()
方法,可以用来遍历对象存储区中的所有数据。
const listAllData = (db) => {
const transaction = db.transaction('myStore', 'readonly');
const store = transaction.objectStore('myStore');
const request = store.openCursor();
request.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
console.log('数据:', cursor.value);
cursor.continue(); // 继续遍历
} else {
console.log('所有数据已遍历完');
}
};
request.onerror = (event) => {
console.error('遍历数据失败', event.target.error);
};
};
总结
- 数据库的打开:通过
indexedDB.open()
打开数据库,如果数据库不存在,则会创建新数据库。 - 对象存储区:通过
createObjectStore()
创建一个对象存储区来存储数据。 - 增、查、改、删操作:通过事务和对象存储区提供的
put()
,get()
,delete()
等方法进行增、查、改、删操作。 - 索引:通过
createIndex()
方法为数据字段创建索引,提高查询效率。 - 事务:使用事务来确保多次操作的原子性。
IndexedDB
适合存储大量数据,并且可以进行高效的查询操作。在需要离线存储大量结构化数据时,它是一个非常合适的选择。