美文网首页
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的二次封装

    前言 浏览器数据库存储indexDB(非关系型数据库),考虑到同步的场景,针对其固有api进行二次封装以满足需求。...

  • 3.保存绘制后的数据,重新进入显示在地图上

    内容需要用到之前封装的IndexedDB,用IndexedDB来保存数据。主要内容: 将绘制的图元保存。 页面加载...

  • indexedDB方法封装

    方法一 方法二 方法三 方法四 方法五 方法六 方法七 方法八 方法九 方法十 方法十一 可以通过es6的方法去全部导出

  • ES6 的 class

    最近又重构了 indexedDB 的封装,因为原来用的 class 的方式封装的,虽然实现了功能,但是感觉挺别扭的...

  • 封装 indexedDB(三)写个插件

    因为要在 vue 里面使用,所以做个插件可以方便很多。 项目需求 第一次访问,初始化,需要建立表、导入初始数据 组...

  • 封装 indexedDB(七)删除对象

    关系型数据库,一般会涉及到是物理删除,还是逻辑删除,而对象数据库,大概直接删掉就好了。 所以简单一点,直接删掉就好...

  • 封装 indexedDB(一)做个help先

    不知道大家有没有发现,我封装了后端的 MySQL,前端的 webSQL,而现在又要对 indexedDB 下手了。...

  • 封装 indexedDB(六)修改对象

    关系型数据库,可以通过SQL指定要修改的字段,而不是必须完整的修改。而对象的修改,是把对象整体放入(替换),如果对...

  • 封装 indexedDB(五)添加对象

    还是按照惯例,介绍一下增删改查的实现方式。 添加对象 相当于关系型数据库里的添加记录。indexedDB的步骤是:...

  • 前端数据存储之IndexedDB

    IndexedDB 一、关于前端数据存储常用的几个方案 Cookie Web Storage IndexedDB ...

网友评论

      本文标题:IndexedDB的二次封装

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