美文网首页
indexedDB 使用记录

indexedDB 使用记录

作者: No刹那光辉 | 来源:发表于2020-04-06 16:52 被阅读0次
由于之前的项目采用过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<any> {
    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有值后才能调用
image.png

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

  /**
   * 获取所有数据
   * @param storeNam 对象名称
   * @param sqlIndex 索引
   * @param indexValue 索引值
   */
  getIndexedDBAll(storeNam: string, sqlIndex: string, indexValue: any): Promise<any> {
    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,如图
image.png
查询最后一条数据
/**
   * 获取最后一条记录
   * @param storeNam 对象名称
   * @param sqlIndex 索引
   * @param indexValue 索引值
   */
  getIndexedDBPrev(storeNam: string, sqlIndex: string, indexValue: any): Promise<any> {
    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<any> {
    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<any> {
    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 使用记录

    由于之前的项目采用过websql作为数据存储,就是因为websql和真机的sqlite都是属于关系型数据库,可以使...

  • IndexedDB的使用教程

    以下是我在学习IndexedDB时做的总结,为了方便以后使用时速查,特意记录如下: 一. IndexedDB介绍 ...

  • IndexedDB(二:索引)

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

  • indexedDB使用

    一.使用指导 1.indexedDB 数据库类似于 NoSQL key-value 的风格实现,原生支持储存 JS...

  • HTML5本地存储IndexedDB基础介绍(二)- 游标和索引

    引用文档: HTML5本地存储——IndexedDB(一:基本使用)HTML5本地存储——IndexedDB(二:...

  • HTML5本地存储IndexedDB基础介绍(-)-数据库的简单

    引用文档: HTML5本地存储——IndexedDB(一:基本使用)HTML5本地存储——IndexedDB(二:...

  • indexedDB学习记录

    浏览器三大本地缓存中,session与local存储的内容数量有限并且不提供查询优化,而indexedDB提供了很...

  • indexedDB使用总结

    前言 最近在做的项目上有离线功能,需要将大量的数据存储在前端。结合项目实际需求最后决定使用indexedDB来进行...

  • IndexedDB的使用

    IndexedDB 是一种低级API,用于客户端存储大量结构化数据(包括文件和blobs)。该API使用索引来实现...

  • indexedDB入门使用

    问题:你在学习indexedDB时你一般从哪几个方面下手呢,有没有一个大致的学习或执行思路? 针对上面的问题,我们...

网友评论

      本文标题:indexedDB 使用记录

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