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

IndexedDB 是浏览器提供的本地数据库,可以在浏览器中存储结构化数据。下面是 IndexedDB 的基本使用方法: 1. 打开数据库 使用 `indexedDB` 对象的 `open()` 方法打开数据库,如下所示: ``` let request = indexedDB.open('myDB', 1); ``` 其中,第一个参数是数据库名称,第二个参数是数据库版本号。如果数据库不存在,则会创建一个新的数据库。 2. 创建对象仓库 在成功打开数据库的回调方法 `request.onsuccess` 中,可以获取到数据库对象 `event.target.result`,然后使用它的 `createObjectStore()` 方法创建一个对象仓库(即数据表),如下所示: ``` let db = event.target.result; let objectStore = db.createObjectStore('people', { keyPath: 'id' }); ``` 其中,第一个参数是对象仓库的名称,第二个参数是一个对象,包含一个 keyPath 属性和其他可选属性。keyPath 用来指定数据表中的主键。 3. 添加数据 使用事务 `db.transaction()` 开启一个事务,然后使用 `add()` 方法向数据表中添加数据,如下所示: ``` let transaction = db.transaction(['people'], 'readwrite'); let objectStore = transaction.objectStore('people'); let request = objectStore.add({ id: 1, name: 'John Doe' }); ``` 其中,第一个参数是一个数组,包含要访问的对象仓库的名称,第二个参数是事务类型,可以是 'readonly' 或 'readwrite'。`add()` 方法的参数是要添加的数据。 4. 查询数据 使用事务 `db.transaction()` 开启一个事务,然后使用 `get()` 方法查询数据,如下所示: ``` let transaction = db.transaction(['people']); let objectStore = transaction.objectStore('people'); let request = objectStore.get(1); request.onsuccess = function(event) { console.log('Name: ' + event.target.result.name); }; ``` `get()` 方法的参数是要查询的数据的主键值。查询结果保存在 `request.onsuccess` 回调方法中的 `event.target.result` 中。 5. 更新数据 使用事务 `db.transaction()` 开启一个事务,然后使用 `put()` 方法更新数据,如下所示: ``` let transaction = db.transaction(['people'], 'readwrite'); let objectStore = transaction.objectStore('people'); let request = objectStore.put({ id: 1, name: 'Jane Doe' }); ``` `put()` 方法的参数是要更新的数据。 6. 删除数据 使用事务 `db.transaction()` 开启一个事务,然后使用 `delete()` 方法删除数据,如下所示: ``` let transaction = db.transaction(['people'], 'readwrite'); let objectStore = transaction.objectStore('people'); let request = objectStore.delete(1); ``` `delete()` 方法的参数是要删除的数据的主键值。 以上就是 IndexedDB 的基本使用方法。需要注意的是,IndexedDB 的 API 非常庞大,不仅仅包含上面提到的这些方法,还包括索引、游标、版本升级等功能。如果需要更详细的介绍和示例代码,可以参考 MDN 的文档:https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值