新建indexedDB.js
// 适配不同浏览器
const indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
// 新建类
class IndexedDBCache {
constructor () {
this._db = null; // 数据库
this._transactionRead = null; // 读取事务
this._transactionWrite = null, // 写入事务
this._request = null;
this._dbName = "logDB"; //数据库名
this._cacheTableName = "logTable"; //表名
this._dbversion = 3; //数据库版本
}
/**
*
* @param {string} val 初始话的主键值
* @returns
*/
initDB (val) {
return new Promise((resolve, reject) => {
this._request = indexedDB.open(this._dbName, this._dbversion); // 打开数据库
// 数据库初始化成功
this._request.onsuccess = (event) => {
this._db = this._request.result;
// this._transactionRead = this._db.transaction(this._cacheTableName, "readonly");
// this._transactionWrite = this._db.transaction(this._cacheTableName, "readwrite");
resolve(event);
};
// 数据库初始化失败
this._request.onerror = (event) => {
reject(event);
};
// 数据库初次创建或更新时会触发
this._request.onupgradeneeded = (event) => {
const db = this._request.result;
const objectStore = db.createObjectStore(this._cacheTableName, {
keyPath: val, // 设置主键
autoIncrement: true
});
objectStore.createIndex('projectIdIndex', 'projectId', {unique: false})
objectStore.createIndex('timeIndex', 'time', {unique: false})
resolve(event);
};
});
}
closeDB() {
this._db.close();
console.log(`关闭数据库`);
}
/**
*
* @param {object} params 要存储的对象
* @returns
*/
addData(params) {
return new Promise((resolve, reject) => {
const transaction = this._db.transaction(this._cacheTableName, "readwrite");
const objectStore = transaction.objectStore(this._cacheTableName);
// 获取存储中的最大主键值
const getMaxKeyRequest = objectStore.openCursor(null, 'prev');
getMaxKeyRequest.onsuccess = () => {
const cursor = getMaxKeyRequest.result
const key = (cursor? cursor.key : -1) + 1
params.id = key
const response = objectStore.add(params);
// 操作成功
response.onsuccess = (event) => {
console.log("操作成功");
resolve(event);
};
// 操作失败
response.onerror = (event) => {
console.log("操作失败");
reject(event);
};
}
});
}
/**
* 通过主键读取数据
* @param {string} key 要读取的主键值
* @returns
*/
getDataByKey(key) {
return new Promise((resolve, reject) => {
const transaction = this._db.transaction(this._cacheTableName, "readonly");
const objectStore = transaction.objectStore(this._cacheTableName);
// 通过主键读取数据
const request = objectStore.get(key);
// 操作成功
request.onsuccess = () => {
resolve(request.result);
};
// 操作失败
request.onerror = (event) => {
reject(event);
};
});
}
/**
* 范围查询
* @param {string} key 查询的主键值
* @param {any} min 查询范围的最小值
* @param {any} max 查询范围的最大值
* @returns 符合范围的数组
*/
getDataRange(key, min, max) {
return new Promise((resolve, reject) => {
const transaction = this._db.transaction(this._cacheTableName, "readonly");
const objectStore = transaction.objectStore(this._cacheTableName);
const request = objectStore.index(`${key}Index`).openCursor(IDBKeyRange.bound(min, max))
const list = []
// 操作成功
request.onsuccess = () => {
if (request.result) {
const {value} = request.result
value.time = dayjs(value.time).format('YYYY-MM-DD hh:mm:ss')
list.push(value)
request.result.continue()
} else {
resolve(list)
}
};
// 操作失败
request.onerror = (event) => {
reject(event);
};
})
}
/**
* 范围查询方法2
* @param {string} key 查询的主键值
* @param {any} min 查询范围的最小值
* @param {any} max 查询范围的最大值
* @returns 符合范围的数组
*/
getRange(key, min, max) {
return new Promise((resolve, reject) => {
const transaction = this._db.transaction(this._cacheTableName, "readonly");
const objectStore = transaction.objectStore(this._cacheTableName);
/**
* getAll 法返回一个IDBRequest对象,该对象包含对象存储中与指定参数匹配的所有对象,如果没有给出参数,则返回存储中的所有对象。
* @param {object} query 要查询的键或IDBKeyRange。如果不传递任何信息,则默认为选择此对象存储中的所有记录的键范围。
* @param {number} count 指定如果找到多个值要返回的值的数量。如果它小于0或大于2^32 - 1,则会抛出TypeError异常。
* @example objectStore.getAll(IDBKeyRange.bound(min, max), 10)
*/
const request = objectStore.index(`${key}Index`).getAll(IDBKeyRange.bound(min, max))
// 操作成功
request.onsuccess = () => {
console.warn(request.result, 'request.result')
resolve(request.result)
}
// 操作失败
request.onerror = (event) => {
reject(event);
};
})
}
/**
* 分页查询
* @param {object} params key查询主键值,page页码,pageSize每页数量
* @returns
*/
getByPage({key, page, pageSize}) {
return new Promise((resolve, reject) => {
const transaction = this._db.transaction(this._cacheTableName, "readonly");
const objectStore = transaction.objectStore(this._cacheTableName);
const keys = objectStore.index('timeIndex').getAllKeys()
const countResult = objectStore.count()
keys.onsuccess = () => {
console.warn(keys.result)
const allkeys = keys.result
// 获取当前分页开始位置ID
const start = (page - 1) * pageSize
// 获取分页起始位
const lowerkey = IDBKeyRange.lowerBound(allkeys[start])
// 获取分页数据
const alls = objectStore.getAll(lowerkey, pageSize)
alls.onsuccess = () => {
resolve({
list: alls.result,
total: countResult.result
})
}
alls.onerror = (err) => {
reject(err)
}
}
keys.onerror = (err) => {
reject(err)
}
})
}
/**
* 分页模糊查询
* @param {object} params key查询主键值,page页码,pageSize每页数量
* @returns
*/
getByKeyPage ({key, page, pageSize}) {
return new Promise((resolve, reject) => {
const transaction = this._db.transaction(this._cacheTableName, "readonly");
const objectStore = transaction.objectStore(this._cacheTableName);
// 结果列表
const list = []
// 结果区间
const start = (page - 1) * pageSize
const end = start + pageSize
let index = 0
const request = objectStore.openCursor(null, 'prev')
request.onsuccess = () => {
const result = request.result
if (result) {
if (result.value.name.includes(key)) {
if (index >= start && index < end) {
list.push(result.value)
}
index ++
}
request.result.continue()
} else {
resolve(list)
}
}
})
}
// 清空数据库数据
clearDB() {
return new Promise((resolve, reject) => {
const transaction = this._db && this._db.transaction(this._cacheTableName, "readwrite");
const store = transaction && transaction.objectStore(this._cacheTableName);
const response = store && store.clear();
// 操作成功
response.onsuccss = (event) => {
console.log("清空数据库数据");
resolve(event);
};
// 操作失败
response.onerror = (event) => {
reject(event);
};
});
}
/**
*
* @param {string} dbName 数据库名称
* @returns
*/
deleteDBAll(dbName) {
console.log(dbName);
const deleteRequest = indexedDB.deleteDatabase(this._dbName);
return new Promise((resolve, reject) => {
deleteRequest.onerror = function (event) {
console.log("删除失败");
reject(event)
};
deleteRequest.onsuccess = function (event) {
console.log("删除数据库成功");
resolve()
};
});
}
}
export default IndexedDBCache
页面中使用
import IndexedDBCache from '@/utils/indexedDB'
// 初始化数据库
const initIndexDB = () => {
state.db = new IndexedDBCache()
state.db.initDB('id').then(res => {
if (res.type === 'upgradeneeded') {
console.log('数据库创建或更新成功')
initIndexDB()
} else {
console.log('数据库初始化成功')
}
}).catch((err) => {
console.log('数据库初始化失败', err)
})
}
const getByKeyPage = (key, page, pageSize) => {
state.db.getByKeyPage({key, page, pageSize}).then(res => {
console.log('数据获取成功', res)
}).catch(err => {
console.log('数据获取失败', err)
})
}
const setData = (row) => {
state.db.addData(row).then(res => {
console.log('写入数据库成功', res)
}).catch(err => {
console.log('写入数据库失败', err)
})
}
const getDataByName = (name) => {
state.db.getDataByKey(name).then(res => {
console.log('数据获取成功', res)
}).catch(err => {
console.log('数据获取失败', err)
})
}
const getDataRange = (key, min, max) => {
state.db.getDataRange(key, min, max).then(res => {
console.log('数据获取成功', res)
}).catch(err => {
console.log('数据获取失败', err)
})
}
const getByPage = (params) => {
state.db.getByPage(params).then(res => {
console.log('数据获取成功', res)
}).catch(err => {
console.log('数据获取失败', err)
})
}