美文网首页
IndexedDB的二次封装

IndexedDB的二次封装

作者: 得到世界又如何我的心中只有你 | 来源:发表于2020-06-18 21:59 被阅读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()
    

    相关文章

      网友评论

          本文标题:IndexedDB的二次封装

          本文链接:https://www.haomeiwen.com/subject/mlxbtktx.html