设计思路
固定数据表
- 键值对表
用于存储数据库相关的信息 - 库字段构成表
储存非固定数据表结构
非固定数据表
通过库字段构成表进行创建或更新
划重点
- 数据库初始创建或更新后会先触发onupgradeneeded方法,然后再触发onsuccess方法,如果在onupgradeneeded方法中执行了表结构操作的话,onsuccess会在transaction.oncomplete事件处理之后触发,所以在onsuccess方法中去执行增删改一定是在表完整结构基础上不必担心表错误
先上封装的代码
class indexedDBClass {
db
tableName
keyPath
// 连接数据库
openDB(dbName) {
return new Promise((resolve, reject) => {
const request = indexedDB.open(dbName);
// 创建或更新成功
request.onupgradeneeded = (e) => {
const db = e.target.result;
this.initDB(db);
};
// 连接成功
request.onsuccess = (e) => {
resolve(e.target.result);
};
// 连接失败
request.onerror = (e) => {
reject(e.target.errorCode);
};
});
}
// 初始化数据库
initDB(db) {
this.keyPath = 'id'
const objStore = db.createObjectStore(this.tableName, { keyPath: 'id' });
objStore.createIndex('name', 'name', { unique: false })
}
// 插入一条数据
putDataOnce(obj) {
return new Promise((resolve, reject) => {
let request = this.db.transaction([this.tableName], 'readwrite').objectStore(this.tableName).put(obj)
request.onsuccess = function () {
resolve()
}
request.onerror = function () {
reject()
}
})
}
// 插入数据
putData(list) {
let arr = [].concat(list)
return new Promise((resolve, reject) => {
Promise.all(arr.map(v => this.putDataOnce(v)))
.then(res => {
resolve()
}).catch(err => {
reject()
})
})
}
// 通过主键删除数据
delDataByKeyPath(keyPath) {
return new Promise((resolve, reject) => {
let request = this.db.transaction([this.tableName], 'readwrite').objectStore(this.tableName).delete(keyPath)
request.onsuccess = function () {
resolve()
}
request.onerror = function () {
reject()
}
})
}
// 删除数据
delData(obj) {
// 由于只能通过主键删除数据,所以要先根据条件进行查询,后逐条进行删除操作
return new Promise((resolve, reject) => {
this.getData(obj).then(res => {
return Promise.all(res.map(v => this.delDataByKeyPath(v.id)))
}).then(res => {
resolve()
}).catch(err => {
reject()
})
})
}
// 获取数据
getData(obj) {
const objectStore = this.db.transaction(this.tableName).objectStore(this.tableName);
let objKeyList = Object.keys(obj)
return new Promise((resolve, reject) => {
let arr = []
objectStore.openCursor().onsuccess = ({ target: { result } }) => {
if (result) {
if (objKeyList.every(v => obj[v] === result.value[v])) {
arr.push(result.value)
}
result.continue();
} else {
resolve(arr)
}
}
})
}
// 构造方法
constructor(tableName, cb, dbName = '***') {
this.tableName = tableName;
this.openDB(dbName).then((res) => {
this.db = res;
cb()
});
}
}
使用的时候先创建数据库表
collegeDB = new indexedDBClass('college', () => {
// 这里的'college'是表名,数据库名默认为'***',可以传第三个参数更换数据库名
// 使用数据库的代码都要在这里面运行,不然会出现数据库未链接就使用的情况
// 获取数据(参数是匹配条件)
let list = await collegeDB.getData({ name: '张三' })
// 新增&插入数据(参数是完整的要存储的数据)
await collegeDB.putData(list)
// 删除数据(参数是匹配条件)
await collegeDB.delData({ name: '张三' })
})
整个使用下来给我一种就是把数据存在本地的错觉,而且相当不好用,特别是批量处理相当不友好,对于布尔值的搜索还会报错(所以获取数据变成获取全部数据再用js匹配筛选),个人感觉自己写页面玩一玩就得了,要不是谷歌不支持websql我是真的不想研究这玩意
标签:IndexedDB,resolve,封装,request,tableName,db,Promise,reject,设计 From: https://www.cnblogs.com/dkf717/p/17835473.html