前言
浏览器数据库存储indexDB
(非关系型数据库),考虑到同步的场景,针对其固有api
进行二次封装以满足需求。
初始化数据库
考虑到每次使用api
都要基于db进行操作,且需要判断是否进行过数据库的开启,定义公用方法openDB
来获取db并进行存储。
openDB() {
return new Promise((resolve, reject) => {
// 判断是否已经打开数据库
if (this.db) {
resolve(this.db)
} else {
const request = window.indexedDB.open('库的名字')
// 首次创建数据库
request.onupgradeneeded = (event) => {
const db = event.target.result
// to do something...
}
request.onsuccess = () => {
this.db = request.result
resolve(request.result)
}
request.onerror = (error) => { reject(error) }
}
})
}
创建表
当创建完数据库后,对所需的表进行创建;
可以创建对象不得缺少指定属性的表{ keyPath: 'id' }
,或者是使用自动递增的整数作为键名的表{ autoIncrement: true }
。
// ... ...
// 首次创建数据库
request.onupgradeneeded = (event) => {
const db = event.target.result
// to do something...
db.createObjectStore('表名', { keyPath: 'id' })
db.createObjectStore('表名', { autoIncrement: true })
}
// ... ...
如果需要建立索引(可以根据索引快速查找数据)。
let store = db.createObjectStore('表名', { keyPath: 'id' })
orglistStore.createIndex('索引', '索引', { unique: false })
插入数据
创建完表后,封装插入数据方法setItem
。
/**
* @param {String} name 表名
* @param {Object} obj 数据项
* @param {Any} key 对应的位置
*/
async setItem(name, obj, key = 'object') {
const db = await this.openDB()
// 将key值合并至对象
let newObj = obj
if (key) {
newObj = Object.assign(obj, { key })
}
return new Promise((resolve, reject) => {
const request = db.transaction([name], 'readwrite')
.objectStore(name)
.put(newObj)
request.onsuccess = (event) => {
resolve(request.result)
}
request.onerror = (error) => {
reject(error)
}
})
}
读取数据
1.单项数据获取getItem
,返回的值为对象。
/**
* @param {String} name 表名
* @param {Number} key
*/
async getItem(name, key = 'object') {
const db = await this.openDB()
return new Promise((resolve, reject) => {
const request = db.transaction([name], 'readwrite')
.objectStore(name)
.get(key)
request.onsuccess = (event) => {
resolve(request.result)
}
request.onerror = (error) => {
reject(error)
}
})
}
2.根据索引获取数据
由于可能有匹配多个索引的数据,所以这里进行循环查询,返回的值为数组。
/**
* @param {String} name 表名
* @param {String} index 索引名
* @param {Any} val 索引值
*/
async getItemByIndex(name, index, val) {
const db = await this.openDB()
return new Promise((resolve, reject) => {
let arr = []
const request = db.transaction([name], 'readwrite')
.objectStore(name)
.index(index)
.openCursor(val)
request.onsuccess = (event) => {
let cursor = event.target.result
if (cursor) {
let obj = cursor.value
obj.key = cursor.primaryKey
arr.push(obj)
cursor.continue()
} else {
resolve(arr)
}
}
request.onerror = (error) => {
reject(error)
}
})
}
3.获取表所有数据getAll
,同索引循环表进行查询,返回的值为数组。
/*
* @param {String} name 表名
*/
async getAll(name) {
const db = await this.openDB()
return new Promise((resolve, reject) => {
let arr = []
const request = db.transaction([name], 'readwrite')
.objectStore(name)
.openCursor()
request.onsuccess = function (event) {
let cursor = event.target.result
if (cursor) {
arr.push({ ...cursor.value, key: cursor.key })
cursor.continue()
} else {
resolve(arr)
}
}
request.onerror = (error) => {
reject(error)
}
})
}
数据清理
1.单项数据清除removeItem
。
/*
* @param {String} name 表名
* @param {Any} key
*/
async removeItem(name, key = 'object') {
const db = await this.openDB()
return new Promise((resolve, reject) => {
const request = db.transaction([name], 'readwrite')
.objectStore(name)
.delete(key)
request.onsuccess = function (event) {
resolve()
}
request.onerror = (error) => {
reject(error)
}
})
}
2.清理表clear
。
/*
* @param {String} name 表名
*/
async clear(name) {
const db = await this.openDB()
return new Promise((resolve, reject) => {
const request = db.transaction([name], 'readwrite')
.objectStore(name)
.clear()
request.onsuccess = function (event) {
resolve()
}
request.onerror = (error) => {
reject(error)
}
})
}
尾语
定义类IndexDB
,设置以上方法,导出实例后的对象。
class IndexDB {
constructor () {
this.db = null // 初始化数据库
}
// 定义方法...
}
export default new IndexDB()
网友评论