美文网首页
indexedDB方法封装

indexedDB方法封装

作者: 洛音轩 | 来源:发表于2019-12-02 17:36 被阅读0次
/**
 * Author: luo yinxuan
 * Date: 2019.10.31
 * Description: indexDB方法
 * 使用时一定注意,indexedDB的所有操作都是异步的
 */

方法一

/**
 * 创建数据库或者打开数据库
 * @param {有db属性的对象} myDB
 * @param {DB名,字符串} name
 * @param {DB版本,正整数} ver
 * @param {DB里面的表名,字符串} storeName
 * @param {DB里面的主键名, 字符串} kN
 * @param {索引,字符串|数组} indexName
 */
function openDB (myDB, name, ver, storeName, kN, indexName) { 
  return new Promise((resolve, reject)=>{
    let version = ver || 1; // 没有传入版本,默认为1,版本号只能递增,要创建表只能通过升级版本来实现
    let keyName = kN || ""; // 主键,可以为空,建议设置,方便查询和更新表
    let index = indexName || ""; // 索引
    let request = window.indexedDB.open(name, version);// 打开indexedDB
    request.onsuccess = function(event){
      console.log(event);
      console.log("Open success");
      myDB.db = request.result; // 打开成功后,保存db对象,后续的操作都是基于db对象增删改查的
      resolve(myDB); // 这里主要是为了保存db
    };
    request.onerror = function(event){ // 打开失败
      console.log(event);
      console.log('OPen Error!');
      reject(event);// 抛出错误
    };
    request.onupgradeneeded = function(e) { // 当初始化或者版本升级事件
      myDB.db = e.target.result;
      console.log('DB version changed to ' + version);
//*********************第一代**************************
//  只能创建一张表
      // if (!myDB.db.objectStoreNames.contains(storeName)) { // 当升级的时候判断要创建的表是否已经存在
      //   let  objectStore
      //   if(keyName){ // 如果有主键,按主键创建表
      //     objectStore = myDB.db.createObjectStore(storeName, { keyPath: keyName }); // keyPath 
      //   } else { // 如果没有主键创建自增表
      //     objectStore = myDB.db.createObjectStore(storeName,{autoIncrement: true}); // keyGenerate
      //   }
      //   if(Object.prototype.toString.apply(index) === '[object Array]') { //判断传入的索引是一个还是一组
      //     for(let i =0; i < index.length; i ++) {
      //       objectStore.createIndex(index[i], index[i], {unique: true}); //分别创建索引
      //     }
      //   } else {
      //     objectStore.createIndex(index, index, {unique: true}); //创建一个索引
      //   }
      // }
// *********************************第二代********************************
// 可以创建一张表或者一组表
      if(Object.prototype.toString.apply(storeName) === '[object Array]') { // 一组表
        for(let  i = 0; i < storeName.length; i ++ ) {
          let objectStore;
          if (!myDB.db.objectStoreNames.contains(storeName[i])) {// 当升级的时候判断要创建的表是否已经存在
            objectStore = myDB.db.createObjectStore(storeName[i], { keyPath: keyName[i] }); // keyPath ,根据数组传入的顺序,按主键去创建表
            if(Object.prototype.toString.apply(index) === '[object Array]') { // 是否创建多个索引
              for(let i =0; i < index.length; i ++) {
                objectStore.createIndex(index[i], index[i], {unique: true});
              }
            } else {
              objectStore.createIndex(index, index, {unique: true}); // 创建一个索引
            }
          }
        }
      } else { // 一张表
        if (!myDB.db.objectStoreNames.contains(storeName)) {// 当升级的时候判断要创建的表是否已经存在
          let objectStore;
          if(keyName){
            objectStore = myDB.db.createObjectStore(storeName, { keyPath: keyName }); // keyPath 
          } else {
            objectStore = myDB.db.createObjectStore(storeName,{autoIncrement: true}); // keyGenerate
          }
          if(Object.prototype.toString.apply(index) === '[object Array]') {
            for(let i =0; i < index.length; i ++) {
              objectStore.createIndex(index[i], index[i], {unique: true});
            }
          } else {
            objectStore.createIndex(index, index, {unique: true});
          }
        }
      }
    };
  })
}

方法二

/**
 *添加数据
 * @param {打开或者创建DB时保存的db属性,对象} db
 * @param {表名,字符串} storeName
 * @param {添加的数据,数组} storeData
 */
function addData(db, storeName, storeData) {
  let transaction = db.transaction([ storeName ], 'readwrite');// 通过打开后保存的db对象去激活事务,进行“readwrite”操作
  let store = transaction.objectStore(storeName);//拿到这张表
  for (let i = 0; i < storeData.length; i++) {
    store.add(storeData[i]);// 往表里面add数据
  }
  store.onsuccess = function (event) { //写入成功的回调
    console.log(event)
    console.log("数据写入成功");
  }
  store.onerror = function (event) {//写入失败的回调
    console.log(event)
    console.log("数据写入失败");
  }
}

方法三

/**
 *按索引获取数据
 * @param {打开或者创建DB时保存的db属性,对象} db
 * @param {表名,字符串} storeName
 * @param {索引名索引,字符串} indexName(比如“name”)
 * @param {要查找的值,字符串} value(比如“李四”)
 * @returns {查找到的对象,对象} 
 */
function getDataByIndex(db, storeName, indexName, value){
  let transaction=db.transaction(storeName); // 激活事务
  let store=transaction.objectStore(storeName); // 拿到表
  let index = store.index(indexName); // 得到这个索引名的集合
  index.get(value).onsuccess=function(e){ // 在集合中找到李四这项
    let student=e.target.result;
    return student;
  }
}

方法四

/**
 * 按主键读取数据
 * @param {打开或者创建DB时保存的db属性,对象} db
 * @param {表名,字符串} storeName
 * @param {主键,正整数或者字符串} id
 */
function readData(db, storeName, id) {
  return new Promise((resolve, reject) => {
    let transaction = db.transaction([ storeName ]); // 用表填充事务
    let objectStore = transaction.objectStore(storeName);
    let item = objectStore.get(id); // 通过事务去按主键查找
    item.onerror = function (event) {
      reject(event)
      console.log(event, "事务失败");
    }
    item.onsuccess = function (event) {
      console.log(event, "读取成功");
      if(item.result) {
        resolve(item.result); // 返回查找到的值
      } else {
        reject(false); // 抛出错误
        console.log("读取失败");
      }
    }
  })
}

方法五

/**
 * 利用游标遍历数据
 * @param {打开或者创建DB时保存的db属性,对象} db
 * @param {表名,字符串} storeName
 */
function readAll(db, storeName) {
//**********************第二代*********************************
  return new Promise((resolve) =>{
    let arr=[];
    let transaction = db.transaction([ storeName ]); 
    let  objectStore = transaction.objectStore(storeName); // 用表填充事务
    objectStore.openCursor().onsuccess = function (event) { // 打开游标
      let  cursor = event.target.result; // 获取游标对象
      if(cursor) {
        arr.push(cursor.value); // 用数组存放当前游标所指的值
        cursor.continue(); // 游标指向下一个位置
      } else {
        resolve(arr)
        console.log("没有更多数据了!");
      }
    }
  })
//*********************第一代*************************
    // let arr=[];
    // let transaction = db.transaction([ storeName ]);
    // let  objectStore = transaction.objectStore(storeName);
    // objectStore.openCursor().onsuccess = function (event) {
    //   let  cursor = event.target.result;
    //   if(cursor) {
    //     arr.push(cursor.value)
    //     cursor.continue();
    //   } else {
    //     console.log("没有更多数据了!");
    //   }
    // }
    // return arr;
}

方法六

/**
 *利用游标和索引获取数据
 * @param {打开或者创建DB时保存的db属性,对象} db
 * @param {表名,字符串} storeName
 * @param {要查找的索引,字符串} indexName
 * @param {要查找的值,字符串} value
 * @returns {查找到的数据集合,数组} 
 */
function getMultipleData(db, storeName, indexName, value ){
  // index.openCursor()/index.openKeyCursor()方法在不传递参数的时候会获取object store所有记录,像上面例子一样我们可以对搜索进行筛选可以使用key range 限制游标中值的范围,把它作为第一个参数传给 openCursor() 或是 openKeyCursor()
  // IDBKeyRange.only(value):只获取指定数据
  // IDBKeyRange.lowerBound(value,isOpen):获取最小是value的数据,第二个参数用来指示是否排除value值本身,也就是数学中的是否是开区间
  // IDBKeyRange.upperBound(value,isOpen):和上面类似,用于获取最大值是value的数据
  // IDBKeyRange.bound(value1,value2,isOpen1,isOpen2):不用解释了吧
  let transaction=db.transaction([ storeName ]);
  let store=transaction.objectStore(storeName);
  let iN = indexName || "";
  let vlu = value || "";
  let index = store.index(iN);
  let request=index.openCursor(IDBKeyRange.only(vlu));
  let arr = [];
  request.onsuccess=function(e){
      let cursor=e.target.result;
      if(cursor){
          let student=cursor.value;
          arr.push(student);
          cursor.continue();
      }
  }
}

方法七

/**
 * 清空表
 * @param {打开或者创建DB时保存的db属性,对象} db
 * @param {表名,字符串} storeName
 */
function clearObjectStore(db,storeName){
  let transaction=db.transaction([ storeName ],'readwrite'); 
  let store=transaction.objectStore(storeName); 
  store.clear(); // 清空当前表的所有数据 
}

方法八

/**
 * 更新数据(只有设置主键的时候才能这样更新)
 * @param {打开或者创建DB时保存的db属性,对象} db
 * @param {表名,字符串} storeName
 * @param {要更改的数据,数组} value
 */
function update (db, storeName, value) {
  let transaction = db.transaction([ storeName ], 'readwrite'); // 用表填充事务
  let objectStore = transaction.objectStore(storeName); // 事务操作表
  for(let i = 0; i < value.length; i ++) {
    objectStore.put(value[i]); // 更新表,如果没有添加,如果有比对,不同的话跟新,相同的话不变
  }
  objectStore.onsuccess = function (event) {
    console.log(event, "数据更新成功");
  }
  objectStore.onerror = function (event) {
    console.log(event, "数据更新失败");
  }
}

方法九

/**
 * 按主键删除数据
 * @param {打开或者创建DB时保存的db属性,对象} db
 * @param {表名,字符串} storeName
 * @param {主键,正整数/字符串} id
 */
function remove (db, storeName, id) {
  return new Promise((resolve)=>{
    let transaction = db.transaction([ storeName ], 'readwrite');
    let objectStore = transaction.objectStore(storeName);
    let deleteData = objectStore.delete(id); // 删除主键对应的这条数据
    deleteData.onsuccess = function (event) {
      resolve();
      console.log(event, "数据删除成功");
    }
  })
}

方法十

/**
 * 按表明删除数据库
 * @param {数据库名,字符串} name
 */
function deleteDB(name){
  window.indexedDB.deleteDatabase(name); // 删除indexedDB
}

方法十一

/**
 * 关闭表
 * @param {打开或者创建DB时保存的db属性,对象} db
 */
function closeDB(db){
  db.close(); // 关闭表的打开状态
}
// 实例
// let list = [
//     { 
//       "sguid": null, 
//       "createdate": null, 
//       "approvaltel": null, 
//       "approvalman": null, 
//       "approvalmancd": null, 
//       "custname": "青岛相奎工程机械有限公司",
//       "custtel": "13210127555",
//     },
//   ];
// let myDB = {
//   name: 'myDB',
//   version: 5,
//   db: null,
//   storeName: "list",
//   storeData: list,
//   updateData: {
//     "acceptman": "胡宁",
//     "claimmobile": "dfsadf"
//   },
//   deleteKey: 2 
// };
// openDB(myDB, myDB.name, myDB.version, myDB.storeName);
// setTimeout(() => { //第一代,通过延迟来实现
  // addData(myDB.db, myDB.storeName, myDB.storeData);
  // readData(myDB.db, myDB.storeName, 1);
  // readAll(myDB.db, myDB.storeName);
  // update(myDB.db, myDB.storeName, myDB.updateData);
  // remove(myDB.db, myDB.storeName, myDB.deleteKey);
// }, 3000);

// 第二代
DB.openDB(baseData, "baseData", 1, "index", "compare_value").then((DBres) => { // 将当前角色的menu存在indexedDB中
   DB.addData();
   DB.readData();
   ...
   DB.update(DBres.db, "index", baseArr);
})

可以通过es6的方法去全部导出

export default {
  openDB,
  addData,
  readData,
  readAll,
  update,
  remove,
  deleteDB,
  closeDB,
  clearObjectStore,
  getDataByIndex,
  getMultipleData,
}

相关文章

  • indexedDB方法封装

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

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

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

  • ES6 的 class

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

  • IndexedDB(二:索引)

    在HTML5本地存储——IndexedDB(一:基本使用)中介绍了关于IndexedDB的基本使用方法,很不过瘾,...

  • 封装 indexedDB(三)写个插件

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

  • 封装 indexedDB(七)删除对象

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

  • 封装 indexedDB(一)做个help先

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

  • IndexedDB的二次封装

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

  • 封装 indexedDB(六)修改对象

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

  • 封装 indexedDB(五)添加对象

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

网友评论

      本文标题:indexedDB方法封装

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