操作流程
打开数据库
使用IndexedDB 的第一步是打开数据库,使用indexedDB.open()方法
// 第一个参数是字符串,表示数据库的名字。如果指定的数据库不存在,就会新建数据库
// 第二个参数是整数,表示数据库的版本。如果省略,打开已有数据库时,默认为当前版本;新建数据库时,默认为1
var request = window.indexedDB.open(databaseName, version)
indexedDB.open() 方法返回一个IDBRequest对象。这个对象通过三个事件error、success、upgradeneeded,处理打开数据库的操作结果。
- error 事件
error 事件表示打开数据库失败。
request.onerror = function (event) {
console.log('数据库打开报错')
}
- success 事件
success 事件表示成功打开数据库。
var db
request.onsuccess = function (event) {
db = request.result
console.log('数据库打开成功')
}
// 这时,通过request 对象的 result属性拿到数据库对象。
- upgradeneeded 事件
如果指定的版本号,大于数据库的实际版本号,就会发生数据库升级事件 upgradeneeded。
var db
request.onupgradeneeded = function (event) {
db = event.target.result
}
// 这时通过事件对象的 target.result 属性,拿到数据库实例
新建数据库
新建数据库与打开数据库是同一操作。如果指定的数据库不存在,就会新建。不同之处在于,后续的操作主要在 upgradeneeded 事件的监听函数里面完成,因为这时版本从无到有,所以会触发这个事件。
通常,新建数据库以后,第一件事是新建对象仓库(即新建表)。
// 数据库新建成功后,新增一张叫做person的表格,主键是id
request.onupgradeneeded = function (event) {
db = event.target.result
var objectStore = db.createObjectStore('person', { keyPath: 'id'})
}
// 更好的写法是先判断一下,这张表是否存在,如果不存在再新建。
request.onupgradeneeded = function (event) {
db = event.target.result
var objectStore
if (!db.objectStoreNames.contains('person')) {
objectStore = db.createObjectStore('person', {keyPath: 'id'})
}
}
主键(key)是默认建立索引的属性。比如,数据记录是 { id: 1, name: '张三’ },那么id 属性可以作为主键。主键也可以指定为下一层对象的属性,比如{foo: {bar: ‘baz’}}的foo.bar也可以指定为主键。
如果数据记录里面没有合适作为主键的属性,那么可以让IndexedDB自动生成主键。
// 指定主键为一个递增的整数
var objectStore = db.createObjectStore('person', {autoIncrement: true})
新建对象仓库以后,下一步可以新建索引。
request.onupgradeneeded = function (event) {
db = event.target.result
var objectStore = db.createObjectStore('person', { keyPath: 'id' })
objectStore.createIndex('name', 'name', {unique:false})
objectStore.createIndex('email', 'email', {unique:true})
}
// IDBObject.createIndex() 的三个参数分别为索引名称、索引所在的属性、配置对象(说明该属性是否包含重复的值)
新增数据
新增数据指的是向对象仓库写入数据记录。这需要通过事务完成。
// 写入数据需要新建一个事务。新建时必须指定表格名称和操作模式(“只读”或“读写”)。新建事务以后,通过 IDBTransaction.objectStore(name) 方法,拿到IDBObjectStore 对象,再通过表格对象的add()方法,向表格写入一条记录
function add() {
var request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.add({id:1, name: '张三', age: 24, email: '11@qq.com'})
request.onsuccess = function(event) {
console.log('数据写入成功')
}
request.onerror = function(event) {
console.log('数据写入失败')
}
}
add()
读取数据
读取数据也是通过事务完成。
// objectStore.get() 方法用于读取数据,参数是主键的值。
function read() {
var transaction = db.transaction(['person'])
var objectStore = transaction.objectStore('person')
var request = objectStore.get(1)
request.onerror = function(event) {
console.log('事务失败')
}
request.onsuccess = function(event) {
if (request.result) {
console.log('Name:'+request.result.name)
console.log('Age'+request.result.age)
console.log('Email'+request.result.email)
} else {
console.log('未获得数据记录')
}
}
}
read()
遍历数据
遍历数据表格的所有记录,要使用指针对象IDBCursor。
// 新建指针对象的 openCursor() 方法是一个异步操作,所以要监听success 事件
function readAll() {
var objectStore = db.transaction('person').objectStore('person')
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result
if (cursor) {
console.log(`Id:${cursor.key}`)
console.log(`Name${cursor.value.name}`)
console.log(`Age${cursor.value.age}`)
console.log(`Email${cursor.value.email}`)
cursor.continue()
} else {
console.log('没有更多数据')
}
}
}
readAll()
更新数据
更新数据要使用 IDBObject.put() 方法。
// put() 方法自动更新了主键为1的记录
function update() {
var request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.put({ id: 1, name: '李四', age: 35, email: '11@qq.com' })
request.onsuccess = function(event) {
console.log('数据更新成功')
}
request.onerror = function(event) {
console.log('数据更新失败')
}
}
update()
删除数据
IDBObjectStore.delete() 方法用于删除记录。
function remove() {
var request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.delete(1)
request.onsuccess = function(event) {
console.log('数据删除成功')
}
}
使用索引
索引的意义在于,可以让你搜索任意字段,也就是从任意字段拿到数据记录。
如果不建立索引,默认只能搜索主键(即从主键取值)。
// 假定新建表格的时候,对 name 字段建立了索引。
objectStore.createIndex('name', 'name', { unique: false })
然后从name找到对应的数据记录
var transaction = db.transaction(['person', 'readonly'])
var store = transaction.objectStore('person')
var index = store.index('name')
request.onsuccess = function(e) {
var result = e.target.result
if(result) {
// ...
} else {
// ...
}
}
案例
<template>
<div style="font-size:18px">
<el-button type="primary" @click="createdDB">新建</el-button>
<el-button @click="add">新增</el-button>
<el-button @click="read">读取</el-button>
<el-button @click="readAll">遍历数据</el-button>
<el-button @click="update">更新数据</el-button>
<el-button @click="remove">删除数据</el-button>
</div>
</template>
<script setup>
var request, db, db_table
function createdDB() {
request = window.indexedDB.open('person', '1')
request.onsuccess = function(res) {
db = res.target.result
console.log('成功', res)
}
request.onerror = function(error) {
console.log('失败', error)
}
request.onupgradeneeded = function(event) {
db = event.target.result
var objectStore
if (!db.objectStoreNames.contains('person')) {
objectStore = db.createObjectStore('person',{keyPath: 'id'})
}
objectStore.createIndex('name', 'name', {unique: false})
objectStore.createIndex('email', 'email', {unique: true})
}
}
function add() {
console.log(db)
request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.add({ id: 1, name: '张三', email: '11@qq.com' })
request.onsuccess = function(event) {
console.log('数据写入成功')
}
request.onerror = function(event) {
console.log('数据写入失败')
}
}
function read() {
var transaction = db.transaction(['person'])
var objectStore = transaction.objectStore('person')
request = objectStore.get(1)
request.onerror = function(event) {
console.log('事务失败', event)
}
request.onsuccess = function(event) {
if (request.result) {
console.log(`name:${request.result.name}`)
console.log(`email${request.result.email}`)
} else {
console.log('未获得数据记录')
}
}
}
function readAll() {
var objectStore = db.transaction('person').objectStore('person')
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result
if (cursor) {
console.log(`id:${cursor.key}`)
console.log(`name:${cursor.value.name}`)
console.log(`email:${cursor.value.email}`)
cursor.continue()
} else {
console.log('没有更多数据')
}
}
}
function update() {
request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.put({id: 1, name: 'haha', email: 'haha@qq.com'})
request.onsuccess = function(event) {
console.log('数据更新成功')
}
request.onerror = function(event) {
console.log('数据更新失败')
}
}
function remove() {
request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.delete(1)
request.onsuccess = function(event) {
console.log('数据删除成功')
}
}
</script>
indexedDB对象
indexedDB.open()
indexedDB.open() 方法用于打开数据库。这是一个异步操作,但是会立刻返回一个IDBOpenDBRequest 对象。
var openRequest = window.indexedDB.open('test', 1)
// 打开一个名为test,版本为1的数据库。如果该数据库不存在,则会新建该数据库。
// open() 方法的
// 第一个参数是数据库名称,格式为字符串,不可省略;
// 第二参数是数据库版本,是一个大于0的正整数(0报错),如果该参数大于当前版本,会触发数据库升级。第二个参数可省略,如果数据已存在,将打开当前版本的数据库;如果数据库不存在,将创建版本的数据库,默认版本为1.
打开数据库是异步操作,通过各种事件通知客户端。四种事件:
- success:打开成功
- error:打开失败
- upgradeneeded:第一次打开该数据库,或者数据库版本发生变化
- blocked:上一次的数据库连接还未关闭
第一次打开数据库时,会先触发 upgradeneeded 事件,然后触发 success 事件。
根据不同的需要,对上面4种事件监听函数。
// open() 方法返回的是一个对象(IDBOpenDBRequest),监听函数就定义在这个对象上面。
// success 事件发生后,从openRequest.result 属性可以拿到已经打开的 IndexedDB 数据库对象。
var openRequest = indexedDB.open('test', 1)
var db
openRequest.onupgradeneeded = function(e) {
console.log('upgrading...')
}
openRequest.onsuccess = function(e) {
console.log('success')
db = openRequest.result
}
openRequest.onerror = function(e) {
console.log('Error')
console.log(e)
}
indexedDB.deleteDatabase()
indexedDB.deleteDatabase() 方法用于删除一个数据库,参数为数据库的名字。返回一个 IDBOpenDBRequest 对象,然后对数据库执行异步删除。删除操作的结果会通过事件通知,IDBOpenDBRequest 对象可以监听以下事件。
- success:删除成功
- error:删除报错
// 调用 deleteDatabase() 方法以后,当前数据库的其他已经打开的连接都会接收到 versionchange 事件。
// 注意:删除不能存在的数据库不会报错。
var DBDeleteRequest = window.indexedDB.deleteDatabase('demo')
DBDeleteRequest.onerror = function(event) {
console.log('Error')
}
DBDeleteRequest.onsuccess = function(event) {
console.log('success')
}
indexedDB.cmp()
indexedDB.cmp() 方法比较两个值是否为 indexedDB 的相同的主键。返回一个整数,表示比较的结果:0表示相同,1表示第一个主键大于第二个主键,-1表示第一个主键小于第二个主键。
window.indexedDB.cmp(1, 2) // -1
注意:此方法不能用来比较任意的JavaScript值。如果参数是布尔值或对象,它会报错。
window.indexedDB.cmp(1, true) // 报错
window.indexedDB.cmp({}, {}) // 报错
IDBRequest 对象
IDBRequest 对象表示打开的数据库连接,indexedDB.open() 方法和 indexedDB.deleteDatabase() 方法会返回这个对象。数据库的操作都是通过这个对象完成的。
这个对象的所有错做都是异步操作,要通过readyState属性判断是否完成,如果为 peding 就表示操作正在进行,如果为 done 就表示操作完成,可能成功有可能失败。
操作完成后,触发 success 事件或 error 事件,这时可以通过 result 属性和 error 属性拿到操作结果。如果在pending 阶段,就去读取这两个属性,会报错。
IDBRequest对象有以下属性。
- IDBRequest.readyState:等于 pending 表示操作正在进行,等于 done 表示操作正在完成。
- IDBRequest.result:返回请求的结果。如果请求失败、结果不可用,读取该属性会报错。
- IDBRequest.error:请求失败时,返回错误对象。
- IDBRequest.source:返回请求的来源(比如索引对象或 ObjectStore )。
- IDBRequest.transaction:返回当前请求正在进行的事务,如果不包含事务,返回 null。
- IDBRequest.onsuccess:指定 success 事件的监听函数。
- IDBRequest.onerror:指定 error 事件的监听函数。
IDBOpenDBRequest 对象继承了 IDBRequest 对象,提供了两个额外的事件监听属性。 - IDBOpenDBRequest.onblocked:指定 blocked 事件( upgradeneeded 事件触发时,数据库仍然在使用)监听的函数。
- IDBOpenDBRequest.onupgradeneeded: upgradeneeded 事件的监听函数。
IDBDatabase对象
打开数据成功以后,可以从 IDBOpenDBRequest 对象的 result 属性上面,拿到一个 IDBDatabase 对象,它表示连接的数据库。后面对数据库的操作,都通过这个对象完成。
var db
var DBOpenRequest = window.indexedDB.open('demo', 1)
DBOpenRequest.onerror = function(event) {
console.log('error')
}
DBOpenRequest.onsuccess = function(event) {
db = DBOpenRequest.result
// ...
}
属性
IDBDatabase 对象有一下属性:
- IDBDatabase.name:字符串,数据库名称。
- IDBDatabase.version:整数,数据库版本。数据库第一次创建时,该属性为空字符串。
- IDBDatabase.objectStoreNames:DOMStringList 对象(字符串的集合),包含当前数据的所有 object store 的名字。
- IDBDatabase.onabort:指定 abort 事件(事务中止)的监听函数。
- IDBDatabase.onclose:指定 close 事件(数据库意外关闭)的监听函数。
- IDBDatabase.onerror:指定 error 事件(访问数据库失败)的监听函数。
- IDBDatabase.onversionchange:数据库版本变化时触发(发生upgradeneeded 事件,或调用 indexedDB.deleteDatabase())。
下面是 objectStoreNames 属性的例子。该属性返回一个DOMStringList 对象,包含当前数据库所有对象仓库的名称(即表名),可以使用 DOMStringList 对象的 contains 方法,检查数据库是否包含某个对象仓库。
// 先判断某个对象仓库是否存在,如果不存在就创建该对象仓库。
if (!db.objectStoreNames.contains('firstOS')) {
db.createObjectStore('firstOS')
}
方法
IDBDatabase 对象有以下方法。
- IDBDatabase.close():关闭数据库连接,实际会等所有事务完成后再关闭。
- IDBDatabase.createObjectStore():创建存放数据的对象仓库,类似于传统关系型数据库的表格。返回一个IDBOjectStore对象。该方法只能在 versionchange 事件监听函数中调用。
- IDBDatabase.deleteObjectStore():删除指定的对象仓库。该方法只能在 versionchange 事件监听函数中调用。
- IDBDatabase.transaction():返回一个 IDBTransaction 事务对象。
下面是 createObjectStore() 方法的例子。
// 创建了一个名为 items 的对象仓库,如果该对象仓库已经存在,就会抛出一个错误。为避免该错误,可采用 objectStoreNames 属性,检查已有哪些对象仓库。
var request = window.indexedDB.open('demo', 2)
request.onupgradeneeded = function(event) {
var db = event.target.result
db.onerror = function(event) {
console.log('error')
}
var objectStore = db.createObjectStore('items')
// ...
}
createObjectStore() 方法还可以接受第二个对象参数,用来设置对象仓库的属性。
// keyPath 属性表示主键(由于主键的值不能重复,所以上例存入之前,必须保证数据的 email 属性值都是不一样的),默认值为 null;autoIncrement 属性表示,是否使用自动递增的整数作为主键(第一个数据记录为1,第二个数据记录为2,以此类推),默认为false。一般来说, keyPath 和 autoIncrement 属性只要使用一个就够了,如果两个同时使用,表示主键为递增的整数,且对象不得缺少 keyPath 指定的属性。
db.createOjbectStore('test', { keyPath: 'email' })
db.createObjectStore('test2', { autoIncrement: true }
deleteObjectStore() 方法的例子
var dbName = 'sampleDB'
var dbVersion = 2
var request = indexedDB.open(dbName, dbVersion)
request.onupgradeneeded = function(e) {
var db = request.result
if (e.oldVersion < 1) {
db.createObjectStore('store1')
}
if (e.oldVersion < 2) {
db.deleteObjectStore('store1')
db.createObjectStore('store2')
}
// ...
}
transaction() 方法的例子,该方法用于创建一个数据库事务,返回一个 IDBTransaction 对象。向数据库添加数据之前,必须先创建数据库事务。
var t = db.transaction(['items'], 'readwrite')
transaction() 方法接受两个参数:第一个参数是一个数组,里面是所涉及的对象仓库,通常是只有一个;第二个参数是一个表示操作类型的字符串。目前,操作类型只有两种:readonly(只读)和 readwrite(读写)。添加数据使用 readwrite,读取数据使用 readonly。第二个参数是可选的,省略时默认为 readonly 模式。
IDBObjectStore 对象
IDBObjectStore 对象对应一个对象仓库(object store)。
IDBDatabase.createObjectStore() 方法返回的就是一个 IDBObjectStore 对象。
IDBDatabase 对象的 transaction() 返回一个事务对象,该对象的 objectStore() 方法返回 IDBObjectStore 对象,因此可以采用下面的链式写法。
db.transaction(['test'], 'readonly')
.objectStore('test')
.get(X)
.onsuccess = function (e) {}
属性
IDBObjectStore 对象有以下属性。
- IDBObjectStore.indexNames:返回一个类似数组的对象(DOMStringList),包含了当前对象仓库的所有索引。
- IDBObjectStore.keyPath:返回当前对象仓库的主键。
- IDBObjectStore.name:返回当前对象仓库的名称。
- IDBObjectStore.transaction:返回当前对象仓库所属的事务对象。
- IDBObjectStore.autoIncrement:布尔值,表示主键是否会自动递增。
方法
IDBObjectStore 对象有以下方法。
(1)IDBObjectStore.add()
IDBObjectStore.add() 用于向对象仓库添加数据,返回一个 IDBRequest 对象。该方法只用于添加数据,如果主键相同会报错,因此更新数据必须使用 put() 方法。
objectStore.add(value, key)
该方法接受两个参数,第一个参数是键值,第二个参数是主键,该参数可选,如果省略,默认为 null。
创建事务以后,就可以获取对象仓库,然后使用 add() 方法往里面添加数据了。
var db
var DBOpenRequest = window.indexedDB.open('demo', 1)
DBOpenRequest.onsuccess = function(event) {
db = DBOpenRequest.result
var transaction = db.transaction(['items'], 'readwrite')
transaction.oncomplete = function(event) {
console.log('transaction success')
}
transaction.onerror = function(event) {
console.log('transaction error')
}
var objectStore = transaction.objectStore('item1')
var objectStoreRequest = objectStore.add({foo: 1})
objectStoreRequest.onsuccess = function (event) {
console.log('add data success')
}
}
(2)IDBObjectStore.put()
IDBObjectStore.put() 方法用于更新某个主键对应的数据记录,如果对应的键值不存在,则插入一条新的记录。该方法返回一个 IDBRequest 对象。
objectStore.put(item, key)
该方法接受两个参数,第一个参数为新数据,第二个参数为主键,该参数可选,且只在自动递增时才有必要提供,因为那时主键不包含在数据值里面。
(3)IDBObjectStore.clear()
IDBObjectStore.clear() 删除当前对象仓库的所有记录。该方法返回一个 IDBRequest 对象。
// 该方法不需要参数。
objectStore.clear()
(4)IDBObjectStore.delete()
IDBObjectStore.delete() 方法用于删除指定主键的记录。该方法返回一个 IDBRequest 对象。
// 该方法的参数为主键的值
objectStore.delete(key)
(5)IDBObjectStore.count()
IDBObjectStore.count() 方法用于计算记录的数量。该方法返回一个 IDRequest 对象。
// 不带参数时,该方法返回当前对象仓库的所有记录数量。如果主键或 IDBKeyRange 对象作为参数,则返回对应的记录数据
objectStore.count(key)
(6)IDBObjectStore.getKey()
IDBObjectStore.getKey() 用于获取主键。该方法返回一个 IDBRequest 对象。
// 该方法的参数可以是主键值或 IDBKeyRange 对象
objectStore.getKey(key)
(7)IDBObjectStore.get()
IDBObjectStore.get() 用于获取主键对应的数据记录。该方法返回一个 IDBRequest 对象。
objectStore.get(key)
(8)IDBObjectStore.getAll()
IDBObjectStore.getAll() 用于获取对象仓库的记录。该方法返回一个 IDBRequest 对象。
// 获取所有记录
objectStore.getAll()
// 获取所有符合指定主键或 IDBKeyRange 的记录
objectStore.getAll(query)
// 指定获取记录的数量
objectStore.getAll(query, count)
(9)IDBObjectStore.getAllKeys()
IDBObjectStore.getAllKeys() 用于获取所有符合条件的主键。该方法返回一个 IDBRequest 对象。
// 获取所有记录的主键
objectStore.getAllKeys()
// 获取所有符合条件的主键
objectStore.getAllKeys(query)
// 指定获取主键的数量
objectStore.getAllKeys(query, count)
IDBObjectStore.index()
IDBObjectStore.index() 方法返回指定名称的索引对象 IDBIndex。文章来源:https://www.toymoban.com/news/detail-595271.html
objectStore.index(name)
有了索引以后,就可以针对索引所在的属性读取数据。文章来源地址https://www.toymoban.com/news/detail-595271.html
var t = db.transaction(['people'], 'readonly')
var store = t.objectStore('people')
var index = store.index('name')
var request = index.get('foo')
到了这里,关于IndexedDB的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!