// 浏览器数据库 IndexedDB // [https://wangdoc.com/javascript/bom/indexeddb] // [https://www.ruanyifeng.com/blog/2018/07/indexeddb.html] var db = null export default { /** * 打开数据库 * @param {string} dbName 数据库的名字 * @param {int} version 数据库的版本 * @return {object} 该函数会返回一个数据库实例 */ async openDB(dbName = 'actMgt', version = 1) { return new Promise((resolve, reject) => { // 兼容浏览器 var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; // 打开数据库,若没有则会创建 const request = indexedDB.open(dbName, version); // 数据库打开成功回调 request.onsuccess = function(event) { db = event.target.result; // 数据库对象 // console.log(`数据库打开成功 name: ${db.name} version: ${db.version}`); resolve(db); }; // 数据库打开失败的回调 request.onerror = function(err) { db = null console.log(`数据库打开报错 name: ${db.name} version: ${db.version}`, err); reject(err) }; // 数据库意外关闭的回调 request.onclose = function(event) { db = null console.log(`数据库意外关闭 name: ${db.name} version: ${db.version}`, event); }; // 数据库有更新时候的回调 request.onupgradeneeded = function(event) { // 数据库创建或升级的时候会触发 console.log("数据库有更新"); db = event.target.result; // 数据库对象 var objectStore; if (dbName == 'actMgt') { if (!db.objectStoreNames.contains('mapInfo')) { // 创建存储库 objectStore = db.createObjectStore("mapInfo", { keyPath: "mapId", // 这是主键 // autoIncrement: false // 实现自增 }); // 创建索引,在后面查询数据的时候可以根据索引查 /* objectStore.createIndex("mapName", "mapName", { unique: false }); */ } } }; }); }, /** * 新增数据 * @param {string} storeName 仓库名称 * @param {string} data 数据 */ insertData(storeName, data) { if (db == null) { console.warn('[insertData] IndexedDB 数据库尚未连接') return } var request = db .transaction([storeName], "readwrite") // 事务对象 指定表格名称和操作模式("只读"或"读写") .objectStore(storeName) // 仓库对象 .add(data); request.onsuccess = function(event) { console.log("数据写入成功"); }; request.onerror = function(err) { console.log("数据写入失败", err); }; }, /** * 更新数据 * @param {string} storeName 仓库名称 * @param {object} data 数据 */ updateData(storeName, data) { if (db == null) { console.warn('[updateData] IndexedDB 数据库尚未连接') return } var request = db .transaction([storeName], "readwrite") // 事务对象 .objectStore(storeName) // 仓库对象 .put(data); //put方法有两个参数,第一个参数是要更新的value,第二个参数是要更新的key,如果忽略第二个参数,默认会使用创建存储对象时指定的 keyPath request.onsuccess = function() { console.log("数据更新成功"); }; request.onerror = function(err) { console.log("数据更新失败", err); }; }, /** * 通过主键删除数据 * @param {string} storeName 仓库名称 * @param {object} key 主键值 */ deleteDataByKey(storeName, key) { if (db == null) { console.warn('[deleteDataByKey] IndexedDB 数据库尚未连接') return } var request = db .transaction([storeName], "readwrite") .objectStore(storeName) .delete(key); request.onsuccess = function() { console.log("数据删除成功"); }; request.onerror = function(err) { console.log("数据删除失败", err); }; }, /** * 通过索引和游标删除指定的多条数据 * @param {string} storeName 仓库名称 * @param {string} indexName 索引名 * @param {object} indexValue 索引值 */ deleteDataByIndex(storeName, indexName, indexValue) { if (db == null) { console.warn('[deleteDataByIndex] IndexedDB 数据库尚未连接') return } var store = db.transaction(storeName, "readwrite").objectStore(storeName); var request = store .index(indexName) // 索引对象 .openCursor(IDBKeyRange.only(indexValue)); // 指针对象 request.onsuccess = function(e) { var cursor = e.target.result; var deleteRequest; if (cursor) { deleteRequest = cursor.delete(); // 请求删除当前项 deleteRequest.onsuccess = function() { console.log("游标删除该记录成功"); }; deleteRequest.onerror = function(err) { console.log("游标删除该记录失败", err); }; cursor.continue(); } }; request.onerror = function(err) { console.log("索引游标查询失败", err); }; }, /** * 通过主键读取数据 * @param {string} storeName 仓库名称 * @param {string} key 主键值 */ getDataByKey(storeName, key) { if (db == null) { console.warn('[getDataByKey] IndexedDB 数据库尚未连接') return } return new Promise((resolve, reject) => { var transaction = db.transaction([storeName]); // 事务 var objectStore = transaction.objectStore(storeName); // 仓库对象 var request = objectStore.get(key); // 通过主键获取数据 request.onsuccess = function(event) { // console.log("主键查询结果: ", request.result); resolve(request.result); }; request.onerror = function(err) { console.log("主键查询失败", err); reject(err) }; }); }, /** * 通过游标读取数据 * @param {string} storeName 仓库名称 */ cursorGetAllData(storeName) { if (db == null) { console.warn('[cursorGetAllData] IndexedDB 数据库尚未连接') return } return new Promise((resolve, reject) => { let list = []; var store = db .transaction(storeName, "readwrite") // 事务 .objectStore(storeName); // 仓库对象 var request = store.openCursor(); // 指针对象 // 游标开启成功,逐行读数据 request.onsuccess = function(e) { var cursor = e.target.result; if (cursor) { // 必须要检查 list.push(cursor.value); cursor.continue(); // 遍历了存储对象中的所有内容 } else { console.log("游标读取的数据:", list); resolve(list); } }; request.onerror = function(err) { console.log("游标读取数据失败", err); }; }); }, /** * 通过索引读取数据 * @param {string} storeName 仓库名称 * @param {string} indexName 索引名称 * @param {string} indexValue 索引值 */ getDataByIndex(storeName, indexName, indexValue) { if (db == null) { console.warn('[getDataByIndex] IndexedDB 数据库尚未连接') return } var store = db.transaction(storeName, "readwrite").objectStore(storeName); var request = store.index(indexName).get(indexValue); request.onsuccess = function(e) { var result = e.target.result; console.log("索引查询结果:", result); }; request.onerror = function(err) { console.log("索引查询失败", err); }; }, /** * 通过索引和游标查询多条记录 * @param {string} storeName 仓库名称 * @param {string} indexName 索引名称 * @param {string} indexValue 索引值 */ cursorGetDataByIndex(storeName, indexName, indexValue) { if (db == null) { console.warn('[cursorGetDataByIndex] IndexedDB 数据库尚未连接') return } return new Promise((resolve, reject) => { let list = []; var store = db.transaction(storeName, "readwrite").objectStore(storeName); // 仓库对象 var request = store .index(indexName) // 索引对象 .openCursor(IDBKeyRange.only(indexValue)); // 指针对象 request.onsuccess = function(e) { var cursor = e.target.result; if (cursor) { // 必须要检查 list.push(cursor.value); cursor.continue(); // 遍历了存储对象中的所有内容 } else { console.log("游标索引查询结果:", list); resolve(list); } }; request.onerror = function(err) { console.log("游标索引查询失败", err); }; }); }, /** * 通过索引和游标分页查询记录 * @param {string} storeName 仓库名称 * @param {string} indexName 索引名称 * @param {string} indexValue 索引值 * @param {number} page 页码 * @param {number} pageSize 查询条数 */ cursorGetDataByIndexAndPage( storeName, indexName, indexValue, page, pageSize ) { if (db == null) { console.warn('[cursorGetDataByIndexAndPage] IndexedDB 数据库尚未连接') return } let list = []; let counter = 0; // 计数器 let advanced = true; // 是否跳过多少条查询 var store = db.transaction(storeName, "readwrite").objectStore(storeName); // 仓库对象 var request = store .index(indexName) // 索引对象 .openCursor(IDBKeyRange.only(indexValue)); // 指针对象 request.onsuccess = function(e) { var cursor = e.target.result; if (page > 1 && advanced) { advanced = false; cursor.advance((page - 1) * pageSize); // 跳过多少条 return; } if (cursor) { // 必须要检查 list.push(cursor.value); counter++; if (counter < pageSize) { cursor.continue(); // 遍历了存储对象中的所有内容 } else { cursor = null; console.log("分页查询结果", list); } } else { console.log("分页查询结果", list); } }; request.onerror = function(err) { console.log("分页查询失败", err); }; }, /** * 关闭数据库 * @param {object} db 数据库实例 */ closeDB() { if (db == null) { console.warn('[closeDB] IndexedDB 数据库尚未连接') return } db.close(); db = null // console.log("关闭数据库"); }, /** * 删除数据库 * @param {object} dbName 数据库名称 */ deleteDBAll(dbName) { console.log(dbName); let deleteRequest = window.indexedDB.deleteDatabase(dbName); deleteRequest.onsuccess = function(event) { console.log("删除成功"); }; deleteRequest.onerror = function(err) { console.log("删除失败", err); }; } }