indexedDB 使用记录

由于之前的项目采用过websql作为数据存储,就是因为websql和真机的sqlite都是属于关系型数据库,可以使用sql语句进行操作,后来在实际的使用中,websql由于已被w3c抛弃很久,很多浏览器都不支持,最终决定网页版使用indexedDB进行复杂数据的存储。

以下是真机sqlite之前使用的代码
ionic sqlite 存取数据封装

indexedDB

indexedDB API

1. 启动应用成功后调用创建indexedDB对象库

  indexed_db: any;//H5 indexedDB数据库对象


  /**
   * 创建indexed_db
   */
  createIndexedDB() {
    try {
      let indexedDB = this.win.indexedDB || this.win.webkitIndexedDB || this.win.mozIndexedDB || this.win.msIndexedDB;
      if (indexedDB) {

        const request = indexedDB.open('data.db', '1');
        request.onsuccess = (e: any) => {
          this.indexed_db = e.target.result;
        }
        request.onerror = (e) => {
          console.log('创建数据库失败');
        }
        request.onupgradeneeded = (e) => {
          this.indexed_db = request.result;
          //判断message是否存在,不存在则创建
          if (!this.indexed_db.objectStoreNames.contains('message')) {
            let messageStore = this.indexed_db.createObjectStore('message', {
              keyPath: "id",//主键
              autoIncrement: true//主键是否自增长
            });

            //指定可以被索引的字段,自由组装唯一的索引,可用于条件查询数据,unique: 字段是否唯一
            messageStore.createIndex(SqlIndex.UserId, "userId", {
              unique: false
            });
            messageStore.createIndex(SqlIndex.UserIdType, ['userId', 'msgType'], {
              unique: false
            });
          }
        }

      } else {
        console.log('创建数据库失败');
      }
    } catch (err) {
      console.log('创建数据库失败');
    }
  }
SqlIndex值
//索引类型
export enum SqlIndex {
  UserId = "userId",
  UserIdType = "userId-type",
}

2. 新增数据

 /**
   * 操作IndexedDB
   * @param storeName 对象名称
   * @param data 存储的数据
   */
  insertIndexedDB(storeNam: string, data: any): Promise {
    return new Promise((resolve, reject) => {
      //readwrite 获取读写权限
      let transaction = this.indexed_db.transaction(storeNam, 'readwrite');
      let store = transaction.objectStore(storeNam);
      let request = store.add(data);
      request.onerror = (e) => {
        console.log("insert data failed");
        reject(e);
      }
      request.onsuccess = (e) => {
        resolve(e)
      }
    })
  }
调用示例 创建message时使用了userId和msgType作为索引,索引data对象里必须含有userId和msgType字段
this.insertIndexedDB('message', { userId: 1, msgType: 1, title:'test', state: 0, content: 'content', createTime: new Date().getTime().toString()});
成功后如下图,调用操作语句必须要在insertIndexedDB函数执行成功, this.indexed_db有值后才能调用
indexedDB 使用记录_第1张图片
image.png

3. 查询数据 (不能分页查询)

  /**
   * 获取所有数据
   * @param storeNam 对象名称
   * @param sqlIndex 索引
   * @param indexValue 索引值
   */
  getIndexedDBAll(storeNam: string, sqlIndex: string, indexValue: any): Promise {
    return new Promise((resolve, reject) => {
      let transaction = this.indexed_db.transaction(storeNam, 'readwrite');
      let store = transaction.objectStore(storeNam);
      let request = store.index(sqlIndex).getAll(indexValue);
      request.onerror = (e) => {
        reject(e);
      }
      request.onsuccess = (e) => {
        resolve(e)
      }
    })
  }
调用查询示例
this.getIndexedDBAll('message', SqlIndex.UserIdType, [1, 1]).then(data => {
    if (data.target.result) {
      console.log(data.target.result);
    }
})

// messageStore.createIndex(SqlIndex.UserIdType, ['userId', 'msgType'], {
// unique: false
//});

创建对象库的时候曾经调用以上代码创建索引,索引查询传入的数组[1,1],第一个值表示userId =1,第二个值表示msgType =1,如图
indexedDB 使用记录_第2张图片
image.png
查询最后一条数据
/**
   * 获取最后一条记录
   * @param storeNam 对象名称
   * @param sqlIndex 索引
   * @param indexValue 索引值
   */
  getIndexedDBPrev(storeNam: string, sqlIndex: string, indexValue: any): Promise {
    return new Promise((resolve, reject) => {
      let transaction = this.indexed_db.transaction(storeNam, 'readwrite');
      let store = transaction.objectStore(storeNam);
      let request = store.index(sqlIndex).openCursor(indexValue, 'prev');// 对应的值有 "next" | "nextunique" | "prev" | "prevunique";
      request.onerror = (e) => {
        reject(e);
      }
      request.onsuccess = (e) => {
        resolve(e)
      }
    })
  }
根据条件索引获取数量
/**
   * 获取条数
   * @param storeNam 对象名称
   * @param sqlIndex 索引
   * @param value 索引值
   */
  getIndexedDBCount(storeNam: string, sqlIndex: string, indexValue: any): Promise {
    return new Promise((resolve, reject) => {
      let transaction = this.indexed_db.transaction(storeNam, 'readwrite');
      let store = transaction.objectStore(storeNam);
      let request = store.index(sqlIndex).count(indexValue);
      request.onerror = (e) => {
        reject(e);
      }
      request.onsuccess = (e) => {
        resolve(e)
      }
    })
  }

4. 修改数据,data的数据必须是从库里查询出去,带有索引的数据

 /**
   * 更新数据
   * @param storeNam 对象名称
   * @param data 更新的数据
   */
  updateIndexedDB(storeNam: string, data: any): Promise {
    return new Promise((resolve, reject) => {
      let transaction = this.indexed_db.transaction(storeNam, 'readwrite');
      let store = transaction.objectStore(storeNam);
      let request = store.put(data)
      request.onerror = (e) => {
        reject(e);
      }
      request.onsuccess = (e) => {
        resolve(e)
      }
    })
  }

5. 删除数据,只删除对象库里的某一条数据

 /**
   * 根据key删除
   * @param key 
   */
  deleteIndexedDB(storeNam: string, key: any) {
    var transaction = this.indexed_db.transaction(storeNam, 'readwrite');
    var store = transaction.objectStore(storeNam);
    store.delete(key);
  }

6.清空对象数据,将会删除对象库里的所有数据

/**
   * 清空数据
   * @param storeNam 对象名称
   */
  clearIndexedDB(storeNam: string) {
    var transaction = this.indexed_db.transaction(storeNam, 'readwrite');
    var store = transaction.objectStore(storeNam);
    store.clear();
  }

7. 版本更新(索引更新)

当前版本已经发布,但后期需要追加索引时,修改版本号1为2

 const request = indexedDB.open('data.db', '2');

从而重新触发onupgradeneeded事件,那么在回调函数里面追加新建的代码

request.onupgradeneeded = (e) => {
          this.indexed_db = request.result;
          //判断message是否存在,不存在则创建
          if (!this.indexed_db.objectStoreNames.contains('message')) {
            let messageStore = this.indexed_db.createObjectStore('message', {
              keyPath: "id",//主键
              autoIncrement: true//主键是否自增长
            });

            //指定可以被索引的字段,自由组装唯一的索引,可用于条件查询数据,unique: 字段是否唯一
            messageStore.createIndex(SqlIndex.UserId, "userId", {
              unique: false
            });
            messageStore.createIndex(SqlIndex.UserIdType, ['userId', 'msgType'], {
              unique: false
            });
          }
          // 新增代码
          let objectStore = e.target.transaction.objectStore('message');
          objectStore.createIndex('userId-type-time', ['userId', 'msgType','createTime'], {
            unique: false
          });
      
}

你可能感兴趣的:(indexedDB 使用记录)