IndexedDB的二次封装

2020-06-18  本文已影响0人  得到世界又如何我的心中只有你
前言

浏览器数据库存储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()
上一篇 下一篇

猜你喜欢

热点阅读