前言
瀏覽器數(shù)據(jù)庫(kù)存儲(chǔ)indexDB(非關(guān)系型數(shù)據(jù)庫(kù)),考慮到同步的場(chǎng)景,針對(duì)其固有api進(jìn)行二次封裝以滿(mǎn)足需求。
初始化數(shù)據(jù)庫(kù)
考慮到每次使用api都要基于db進(jìn)行操作,且需要判斷是否進(jìn)行過(guò)數(shù)據(jù)庫(kù)的開(kāi)啟,定義公用方法openDB來(lái)獲取db并進(jìn)行存儲(chǔ)。
openDB() {
return new Promise((resolve, reject) => {
// 判斷是否已經(jīng)打開(kāi)數(shù)據(jù)庫(kù)
if (this.db) {
resolve(this.db)
} else {
const request = window.indexedDB.open('庫(kù)的名字')
// 首次創(chuàng)建數(shù)據(jù)庫(kù)
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) }
}
})
}
創(chuàng)建表
當(dāng)創(chuàng)建完數(shù)據(jù)庫(kù)后,對(duì)所需的表進(jìn)行創(chuàng)建;
可以創(chuàng)建對(duì)象不得缺少指定屬性的表{ keyPath: 'id' },或者是使用自動(dòng)遞增的整數(shù)作為鍵名的表{ autoIncrement: true }。
// ... ...
// 首次創(chuàng)建數(shù)據(jù)庫(kù)
request.onupgradeneeded = (event) => {
const db = event.target.result
// to do something...
db.createObjectStore('表名', { keyPath: 'id' })
db.createObjectStore('表名', { autoIncrement: true })
}
// ... ...
如果需要建立索引(可以根據(jù)索引快速查找數(shù)據(jù))。
let store = db.createObjectStore('表名', { keyPath: 'id' })
orglistStore.createIndex('索引', '索引', { unique: false })
插入數(shù)據(jù)
創(chuàng)建完表后,封裝插入數(shù)據(jù)方法setItem。
/**
* @param {String} name 表名
* @param {Object} obj 數(shù)據(jù)項(xiàng)
* @param {Any} key 對(duì)應(yīng)的位置
*/
async setItem(name, obj, key = 'object') {
const db = await this.openDB()
// 將key值合并至對(duì)象
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)
}
})
}
讀取數(shù)據(jù)
1.單項(xiàng)數(shù)據(jù)獲取getItem,返回的值為對(duì)象。
/**
* @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.根據(jù)索引獲取數(shù)據(jù)
由于可能有匹配多個(gè)索引的數(shù)據(jù),所以這里進(jìn)行循環(huán)查詢(xún),返回的值為數(shù)組。
/**
* @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.獲取表所有數(shù)據(jù)getAll,同索引循環(huán)表進(jìn)行查詢(xún),返回的值為數(shù)組。
/*
* @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)
}
})
}
數(shù)據(jù)清理
1.單項(xiàng)數(shù)據(jù)清除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)
}
})
}
尾語(yǔ)
定義類(lèi)IndexDB,設(shè)置以上方法,導(dǎo)出實(shí)例后的對(duì)象。
class IndexDB {
constructor () {
this.db = null // 初始化數(shù)據(jù)庫(kù)
}
// 定義方法...
}
export default new IndexDB()