简介
IndexDB是一个对象数据库(非关系型,也非KV型),是浏览器提供的一种本地存储技术。相比起localStorage,它能存储更多
的数据(250M左右,根据浏览器的型号不同其大小也不同),而且它能提供更好的数据索引功能。
IndexDB的使用还是比较奇特的,首先我们要创建数据库,而创建数据库的方法是事件处理方法,也就是说,
只有当触发数据库的创建或升级的时候才会执行创建数据库的代码。
而反馈到实际上的代码上:
// 只有当对应的数据库名称不存在或者版本不存在的时候才会执行onupgradeneeded中的创建数据库代码
indexedDB.open(dbName, dbVersion)
而创建数据库的时候也必须要注意,主键是必须要使用的,而且我非常推荐大家同时创建索引来方便我们后续
查找数据。
封装
现在网上能搜索的indexDB的封装已经很多了,但是好像都有很多问题,要么缺头少尾,要么没有定义很
方便明了的接口,要么就是实现的版本太古早,不太符合现代的ES版本的规范……总而言之,我在网上找了
一遍没有找到那种开箱即用的代码,对此还是很失望的。因此我在此给出了一版封装,使用了ES6中的变量
声明方式以及Promise进行封装,接口的定义也比较人性化,希望能够满足你的开发需求。
/**
* 创建数据库连接
* @param {string} dbName 数据库名称
* @param {number} dbVersion 数据库版本
* @return {Promise<unknown>}
*/
const openDB = function (dbName,dbVersion) {
return new Promise((resolve, reject) => {
// 兼容浏览器
let indexedDB =
window.indexedDB
let db = null
const req = indexedDB.open(dbName, dbVersion)
// 操作成功
req.onsuccess = function () {
// 数据库对象
db = req.result
resolve({code: 0, success: true, data: db, msg: '数据库打开成功!'})
}
// 操作失败
req.onerror = function (event) {
reject({code: -1, success: false, data: null, msg: '数据库打开失败!reason:'+event.target})
}
// 创建表和索引
req.onupgradeneeded = function (event) {
// 数据库创建或升级的时候会触发
db = event.target.result // 数据库对象
let objectStore
if (!db.objectStoreNames.contains("task")) {
objectStore = db.createObjectStore("task", {keyPath:"id", autoIncrement: true }) // 创建表
objectStore.createIndex("type", "type", { unique: false }) // 创建索引
}
if(!db.objectStoreNames.contains("schedule")){
objectStore = db.createObjectStore("schedule", {keyPath:"id", autoIncrement: true })
objectStore.createIndex("date","date",{unique: false})
objectStore.createIndex("title","title",{unique: false})
}
}
})
}
/**
* 新增数据
* @param {object} db 数据库实例
* @param {string} storeName 仓库名称
* @param {Object} data 数据
**/
const addData = function (db, storeName, data) {
return new Promise((resolve, reject) => {
console.log(data)
let req = db
.transaction([storeName], 'readwrite')
.objectStore(storeName) // 仓库对象
.add(data)
// 操作成功
req.onsuccess = function () {
console.log('数据写入成功')
resolve({code: 0, success: true, data: null, msg: '数据写入成功!'})
}
// 操作失败
req.onerror = function (event) {
console.log('数据写入失败')
let data = {code: -1, success: false, data: null, msg: '数据写入失败!'+event}
reject(data)
}
})
}
/**
* 更新数据
* @param {object} db 数据库实例
* @param {string} storeName 仓库名称
* @param {object} data 数据
*/
const updateData = function (db, storeName, data) {
return new Promise((resolve, reject) => {
const req = db
.transaction([storeName], 'readwrite')
.objectStore(storeName)
.put(data)
// 操作成功
req.onsuccess = function () {
console.log('数据更新成功')
resolve({code: 0, success: true, data: null, msg: '数据更新成功!'})
}
// 操作失败
req.onerror = function (event) {
console.log('数据更新失败')
let data = {code: -1, success: false, data: null, msg: '数据更新失败!'+event}
reject(data)
}
})
}
/**
*
* @param {object} db 数据库实例
* @param {string} storeName 仓库名称
* @param id 要删除的数据id
* @return {Promise<unknown>}
*/
const deleteData = function (db, storeName, id){
return new Promise((resolve, reject) => {
const req = db
.transaction([storeName], 'readwrite')
.objectStore(storeName)
.delete(id)
// 操作成功
req.onsuccess = function () {
console.log('数据更新成功')
resolve({code: 0, success: true, data: null, msg: '数据更新成功!'})
}
// 操作失败
req.onerror = function (event) {
console.log('数据更新失败')
let data = {code: -1, success: false, data: null, msg: '数据更新失败!'+event}
reject(data)
}
})
}
/**
* 根据索引找数据
* @param {Object} db 数据实例
* @param {string} storeName
* @param {string} indexName
* @param indexValue
* */
const getDataByIndex = function (db,storeName,indexName,indexValue){
if(!db){
return "";
}
let store = db.transaction(storeName, 'readwrite').objectStore(storeName)
let request = store.index(indexName).getAll(indexValue)
return new Promise((resolve, reject) => {
request.onerror = function(e) {
reject(e)
}
request.onsuccess = function(e) {
resolve(e.target.result)
}
})
}
export {openDB,addData,updateData,getDataByIndex,deleteData}