Bootstrap

IndexedDB 封装数据库增删改查方法

const DBVersion = 1 //版本更新

// 新建数据库(数据库名,表名)
export function openDB(dbName, storeName) {
	//返回一个 promise对象,为了实现异步传输(创建promise对象后就会立即执行)
	return new Promise((resolve, reject) => {
		//兼容浏览器
		var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB
		let db, ObjectStore

		//打开数据库,若没有就创建
		const request = indexedDB.open(dbName, DBVersion)

		//调用数据库打开或创建成功回调函数()
		request.onsuccess = event => {
			//获取 数据库对象,里面有很多方法(增删改查)
			db = event.target.result
			// console.log('数据库打开成功!')
			//返回数据库对象
			resolve(db)
		}

		//创建或打开数据库失败回调函数
		request.onerror = event => {
			console.error('数据库打开错误')
			reject(event)
		}

		//数据库更新回调函数。初次创建,后续升级数据库用
		request.onupgradeneeded = event => {
			console.log('数据库更新啦')
			//获取数据库对象
			db = event.target.result
			// 清除旧 objectStore(对旧 objectStore 的数据进行迁移)
			if (db.objectStoreNames.contains(storeName)) {
				// console.log(db.objectStoreNames); DOMStringList 对象
				db.deleteObjectStore(storeName)
			}
			//创建新存储库(存储库名称,对象)-创建表(users表)
			ObjectStore = db.createObjectStore(storeName, {
				//主键,必须唯一
				keyPath: 'id'
				// autoIncrement: true //实现自增加
			})

			//创建索引,在后面查询数据的时候可以根据索引查-创建字段(字段名,索引名,是否唯一:true)
			//可以通过索引来查询
			// indexName索引列名称
			// indexKey索引键值
			// 给对象仓库(数据库表)创建索引,需要使用对象仓库的createIndex()函数,param1 索引名称,param2 配置索引的键值,param3 配置对象 配置该属性是否是唯一的。
			ObjectStore.createIndex('topic', 'topic', { unique: false }) // 创建索引 可以让你搜索任意字段
		}
	})
}

// 插入数据(数据库对象,表名,插入的数据通常为对象)
export function addData(db, storeName, data) {
	return new Promise((resolve, reject) => {
		let request = db
			.transaction([storeName], 'readwrite') // 事务对象 指定表格名称和操作模式("只读"或"读写")
			.objectStore(storeName) // 仓库对象
			.add(data)

		request.onsuccess = function (event) {
			// console.log('数据写入成功')
			resolve(event)
		}

		request.onerror = function (event) {
			reject(event)
			throw new Error(event.target.error)
		}
	})
}

// 通过主键查询数据(数据库对象,表名,主键值)
export function getDataByKey(db, storeName, key) {
	return new Promise((resolve, reject) => {
		var transaction = db.transaction([storeName]) // 事务
		var objectStore = transaction.objectStore(storeName) // 仓库对象
		var request = objectStore.get(key) // 通过主键获取的查询数据
		//失败回调函数
		request.onerror = function (event) {
			console.log('事务失败')
		}
		//查询成功回调函数
		request.onsuccess = function (event) {
			// console.log('主键查询结果: ', request.result)
			//返回值对应的值
			resolve(request.result)
		}
	})
}

// 通过游标查询所有数据(数据库对象,表名)
export function cursorGetData(db, storeName) {
	let list = []
	var store = db
		.transaction(storeName, 'readwrite') // 事务
		.objectStore(storeName) // 仓库对象
	//初始化了一个游标对象(指针对象)
	var request = store.openCursor()
	//成功回调函数, 游标开启成功,逐行读数据
	return new Promise((resolve, reject) => {
		request.onsuccess = function (e) {
			let cursor = e.target.result
			if (cursor) {
				// 将查询值添加到列表中(游标.value=获取值)
				list.push(cursor.value)
				cursor.continue() // 遍历了存储对象中的所有内容
			} else {
				// console.log('游标读取的数据:', list)
				resolve(list)
			}
		}
		request.onerror = function (e) {
			reject(e)
		}
	})
}
// 分页查询
export function cursorGetDataByPage(db, storeName, page, pageSize) {
	let list = []
	var store = db
		.transaction(storeName, 'readwrite') // 事务
		.objectStore(storeName) // 仓库对象
	//初始化了一个游标对象(指针对象)
	var request = store.openCursor()
	let count = store.count()
	//成功回调函数, 游标开启成功,逐行读数据
	return new Promise((resolve, reject) => {
		let index = null
		request.onsuccess = function (e) {
			// let cursor = e.target.result
			// if (cursor) {
			// 	// 将查询值添加到列表中(游标.value=获取值)
			// 	list.push(cursor.value)
			// 	cursor.continue() // 遍历了存储对象中的所有内容
			// } else {
			// 	// console.log('游标读取的数据:', list)
			// 	resolve(list)
			// }
			let res = e.target.result
			if (res) {
				if (index === pageSize - 1) {
					list.push(res.value)
					// console.log('读取数据成功1:', list)
					// console.log('总条目', count.result)
					resolve({ code: 200, list, count: count.result })
					return
				}
				if (index === null && page !== 1) {
					// console.log('读取跳过:', (page - 1) * pageSize)
					index = 0
					res.advance((page - 1) * pageSize)
				} else {
					index++
					// console.log(res.value)
					list.push(res.value)
					res.continue()
				}
			} else {
				// console.log('读取数据成功2:', list)
				// console.log('总条目', count.result)
				resolve({ code: 200, list, count: list.length == 0 ? list.length : count.result })
			}
		}
		request.onerror = function (e) {
			reject(e)
		}
	})
}

// 通过索引查询,查询满足相等条件的第一条数据(数据库对象,表名,索引名字,索引值)
export function getDataByIndex(db, storeName, indexName, indexValue) {
	//通过Promise实现异步回调
	return new Promise((resolve, reject) => {
		var store = db.transaction(storeName, 'readwrite').objectStore(storeName)
		var request = store.index(indexName).get(indexValue)
		//查询失败回调函数
		request.onerror = function () {
			console.log('查询失败')
		}
		//查询成功回调函数
		request.onsuccess = function (e) {
			var result = e.target.result
			// console.log(typeof (result));
			//返回成功查询数据
			resolve(result)
		}
	})
}

// 通过索引和游标【单一条件】查询多条匹配的数据(数据库对象,表名,索引名,索引值)
export function cursorGetDataByIndex(db, storeName, indexName, indexValue) {
	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 (e) {
			console.log('search error')
		}
	})
}
// 根据索引和游标【多重条件】查询多条匹配的数据(数据库对象,表名,索引名,多个索引值数组[])
export function mutipleSearchByIndex(db, storeName, indexName, indexValues) {
	return new Promise((resolve, reject) => {
		let list = []
		var store = db.transaction(storeName, 'readwrite').objectStore(storeName) // 仓库对象
		var request = store
			.index(indexName) // 索引对象
			.openCursor(IDBKeyRange.only(indexValues)) // 指针对象

		request.onsuccess = function (e) {
			var cursor = e.target.result
			if (cursor) {
				// 必须要检查
				list.push(cursor.value)
				cursor.continue() // 遍历了存储对象中的所有内容
			} else {
				// console.log("游标索引查询结果:", list);
				console.log('读取数据成功')
				resolve(list)
			}
		}
		request.onerror = function (e) {
			console.log('search error')
		}
	})
}
// 模糊查询
export function fuzzySearch(db, storeName, keyword) {
	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) {
				if (cursor.value.topic.indexOf(keyword) !== -1) {
					// 必须要检查
					list.push(cursor.value)
				}
				cursor.continue() // 遍历了存储对象中的所有内容
			} else {
				// console.log("游标索引查询结果:", list);
				resolve({ code: 200, list })
			}
		}
		request.onerror = function (e) {
			console.log('search error')
		}
	})
}

// 通过提供的主键值来更新数据,如果主键值不存在,就添加数据(数据库对象,表名,新的数据值)
export function updateDB(db, storeName, data) {
	return new Promise((resolve, reject) => {
		var request = db
			.transaction([storeName], 'readwrite') // 事务对象
			.objectStore(storeName) // 仓库对象
			.put(data)

		request.onsuccess = function () {
			// console.log("数据更新成功");
			resolve('数据更新成功')
		}
		request.onerror = function () {
			// console.log("数据更新失败");
			reject('数据更新失败')
		}
	})
}

// 通过主键删除数据(数据库对象,表名,主键值)
export function deleteDB(db, storeName, id) {
	return new Promise((resolve, reject) => {
		var request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(id)

		request.onsuccess = function (e) {
			// console.log("数据删除成功");
			resolve('删除成功')
		}
		request.onerror = function () {
			// console.log("数据删除失败");
			reject('删除失败')
		}
	})
}

// 通过游标和索引删除指定的多条数据(数据库对象,表名,索引名,索引值)
export function cursorDelete(db, storeName, indexName, indexValue) {
	return new Promise((resolve, reject) => {
		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.onerror = function () {
					// console.log("游标删除该记录失败");
					reject('删除失败!')
				}
				deleteRequest.onsuccess = function () {
					// console.log("游标删除该记录成功");
					resolve('删除成功!')
				}
				cursor.continue()
			}
		}
		request.onerror = function (e) {}
	})
}

// 关闭数据库
export function closeDB(db) {
	return new Promise((resolve, reject) => {
		db.close()
		resolve('数据库已关闭')
	})
}
function promiseForRequest(request) {
	return new Promise((resolve, reject) => {
		request.onsuccess = () => {
			resolve(request.result)
		}
		request.onerror = () => {
			reject(request.error)
		}
	})
}

注意: 调用方法时要用async await

;