/**
* 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,
}
网友评论