IndexedDB 基础入门

Published on
7 mins read
––– views

IndexedDB

Cookie 的大小通常为4KB;LocalStorage 的大小通常在 2.5MB 到 10MB 之间,且它不提供搜索功能,也不能建立自定义的索引。因此,它们都不适合存储大量的数据。为了填补浏览器在这方面的不足,IndexedDB 应运而生。

IndexedDB 是浏览器提供的本地数据库,它是一个事务型数据库系统,可以通过网页脚本创建和操作。相较于LocalStorage,IndexedDB 更适合存储大量的数据。它具备查找接口和建立索引的功能,而这些是 LocalStorage 所不具备的。与传统的关系型数据库不同,IndexedDB 不支持 SQL 查询语句,更类似于 NoSQL 数据库。

打开数据库

IndexedDB 可以直接打开,如果指定的数据库不存在时会自动新建数据库。

open 方法可以传入两个参数:第一个参数是数据库名称,第二个参数是数据库版本。数据库的版本不传时默认时当前版本,如果数据库不存在自动新建数据库时版本默认为 1

const request = indexedDB.open(databaseName, version)

open 方法返回的是一个 IDBRequest 实例。

如果 request 对象成功执行了,结果可以通过 result 属性访问到,并且该 request 对象上会触发 success 事件。

如果操作中有错误发生,一个 error 事件会触发,并且会通过 result 属性抛出一个异常。

如果指定的版本大于当前版本,则会出发 upgradeneeded 事件,当数据库不存在自动创建数据库时也会触发这个事件。

const request = window.indexedDB.open('testDB')
request.onsuccess = (event) => {
  const db = event.target.result
  console.log('Database opened successfully!')
}
request.onerror = (event) => {
  console.log('Database opened failed!')
}
request.onupgradeneeded = (event) => {
  console.log('Database upgrade needed!')
}

新建“表”

打开或新建数据库后,通过 result 拿到数据库对象,后续的操作我们都在此对象上进行。

通过 createObjectStore 方法可以创建一个 store,也就相当于是表。

// version 默认为 1
const request = indexedDB.open('testDB')

request.onupgradeneeded = (event) => {
  const db = event.target.result
  let objectStore
  if (!db.objectStoreNames.contains('user')) {
    objectStore = db.createObjectStore('user', { keyPath: 'id' })
  }
}

通过以上代码,打开数据库,判断 user 数据库是否存在,如果不存在泽新建一个名为 user 的表,并指定主键为 id

主键(key)是默认建立索引的属性。比如,数据记录是 { id: 1, name: '张三' },那么 id 属性可以作为主键。主键也可以指定为下一层对象的属性,比如 { foo: { bar: 'baz' } }foo.bar 也可以指定为主键。

如果数据记录里面没有合适作为主键的属性,那么可以让 IndexedDB 自动生成主键。下面代码中,指定主键为一个递增的整数。

objectStore = db.createObjectStore('user', { autoIncrement: true })

创建索引

可以通过 createIndex 方法创建表索引。

request.onupgradeneeded = function (event) {
  db = event.target.result
  var objectStore = db.createObjectStore('user', { keyPath: 'id' })
  objectStore.createIndex('name', 'name', { unique: false })
  objectStore.createIndex('age', 'age', { unique: true })
}

操作数据

使用 IndexedDB,可以轻松地向数据库中添加新的数据。可以通过创建对象存储空间(Object Store)来存储数据,并使用事务来确保数据的完整性和一致性。

const transaction = db.transaction('user', 'readwrite')
const objectStore = transaction.objectStore('user')

const data = { id: 1, name: 'Mengke', age: 26 }
const request = objectStore.add(data)

request.onsuccess = () => {
  console.log('数据添加成功')
}

上面代码中,写入数据需要新建一个事务。新建时必须指定表格名称和操作模式("只读"或"读写")。新建事务以后,通过 IDBTransaction.objectStore(name) 方法,拿到 IDBObjectStore 对象,再通过表格对象的 add() 方法,向表格写入一条记录。

写入操作是一个异步操作,通过监听连接对象的 success 事件和 error 事件,了解是否写入成功。

如果需要从数据库中删除某些数据,可以使用事务来删除特定的对象或整个对象存储空间。

const transaction = db.transaction('user', 'readwrite')
const objectStore = transaction.objectStore('user')

const request = objectStore.delete(1)

request.onsuccess = () => {
  console.log('数据删除成功')
}

当需要修改已有的数据时,可以使用事务来更新数据。通过指定要更新的对象存储空间和键值,可以进行数据的修改。

const transaction = db.transaction('user', 'readwrite')
const objectStore = transaction.objectStore('user')

const request = objectStore.get(1)

request.onsuccess = (event) => {
  const data = event.target.result
  data.age = 27

  const updateRequest = objectStore.put(data)
  updateRequest.onsuccess = () => {
    console.log('数据更新成功')
  }
}

一旦数据存储在数据库中,可以使用查询操作来检索所需的数据。可以根据特定的关键字或范围进行查询,并获取相应的数据结果。

const transaction = db.transaction('user', 'readonly')
const objectStore = transaction.objectStore('user')

const request = objectStore.get(1)

request.onsuccess = (event) => {
  const data = event.target.result
  console.log(data)
}

遍历数据

IndexedDB 还提供了遍历数据的功能。可以使用游标(Cursor)来逐个迭代数据库中的数据,并进行相应的操作。

const transaction = db.transaction('user', 'readonly')
const objectStore = transaction.objectStore('user')

const request = objectStore.openCursor()

request.onsuccess = (event) => {
  const cursor = event.target.result
  if (cursor) {
    console.log(cursor.value)
    cursor.continue()
  }
}

索引

在 IndexedDB 中,可以创建索引来提升数据的查询性能。索引可以根据特定的字段对数据进行排序和过滤,加快数据检索的速度。

const objectStore = db.createObjectStore('user', { keyPath: 'id' })
objectStore.createIndex('nameIndex', 'name', { unique: false })

(完)

Built with
-View source
Copyright © 2024
Mengke's blog - Mengke's coding journey