indexedDB|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|indexedDB 使用记录
文章图片
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|indexedDB 使用记录
文章图片
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');

【indexedDB|indexedDB 使用记录】从而重新触发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 }); }

    推荐阅读