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