indexdb简介
indexdb是一种浏览器本地化存储,与之功能类似的有cookie(4k),localstorage(5M-10M)。 但是indexdb的存储空间更大,是一种非关系型的本地数据库。
项目中需要对用户所绘制的path路径进行存储,以便下次访问时直接读取渲染在页面上,考虑到存储空间大小的问题,所以选择了indexdb进行存储。
indexdb的优点如下:
1、IndexedDB顾名思义是一种内置在浏览器中数据库,而且是一种非关系型的数据库,即不需要编写SQL语句去操作数据库,而且存储的数据格式是JSON。
2、IndexedDB不像我们平时服务器上使用的 NoSQL 数据库,IndexedDB没有表的概念,在IndexedDB中是叫object store,其实平时就可以把object store看做数据表。
3、IndexedDB的每次操作都是一个事务,每一个对数据库操作是在一个事务的上下文中执行的。
4、IndexedDB的每次数据库操作都需要先打开object store,再执行指定的操作,不能一直打开某个object store。
5、IndexedDB的所有操作都是异步的。
indexdb的封装
数据库的基本信息
private dbName: string = 'svgData';//数据库名称
private version: number = 1;//数据库版本
private tableName: string = 'svgPath';//数据表名称
private db: IDBDatabase | null = null;
数据库的打开 创建数据表
openDB = () => {
return new Promise((resolve,reject)=>{
const request = window.indexedDB.open(this.dbName, this.version);
request.onsuccess = (event: any) => {//数据库打开成功
console.log('成功打开数据库')
this.db = event.target.result
resolve(1);
};
request.onupgradeneeded = (event:any) => {
console.log('成功新建数据库')
this.db = event.target.result;
this.create_table(this.db);
}
request.onerror = (event:any) => {
console.log('数据库打开报错');
reject(1);
};
})
}
//新建数据表
create_table = (idb: any) => {
if (!idb.objectStoreNames.contains(this.tableName)) {
let objectStore;
objectStore = idb.createObjectStore(this.tableName, { keyPath: 'id' });
objectStore.createIndex('id', 'id', { unique: true });
}
}
读取所有数据(使用游标来进行遍历)
readAll = () => {
return new Promise((resolve,reject)=>{
if(this.db){
let objectStore = this.db.transaction(this.tableName).objectStore(this.tableName);
objectStore.openCursor().onsuccess = function (event:any) {
var cursor = event.target.result;
if (cursor) {
UIStore.initPathList(cursor.key,cursor.value);
cursor.continue();
} else {
console.log('没有更多数据了!');
resolve(1);
}
};
}
else{
reject();
}
})
}
增加数据
add = (newPath:any) => {
if(this.db){
let path = toJS(newPath);
let request = this.db.transaction([this.tableName], 'readwrite')
.objectStore(this.tableName)
.add(path);
request.onsuccess = function (event:any) {
console.log('数据写入成功');
};
request.onerror = function (event:any) {
console.log('数据写入失败'+event);
}
}
}
更新数据
因为项目中数据更新的频率很高,所以给indexdb的数据更新进行了防抖处理
update = _.debounce((newPath:any)=> {
if(this.db){
let path = toJS(newPath);
let request = this.db.transaction([this.tableName], 'readwrite')
.objectStore(this.tableName)
.put(path);
request.onsuccess = function (event:any) {
console.log('数据更新成功');
};
request.onerror = function (event:any) {
console.log('数据更新失败');
}
}
},1000,{ 'maxWait': 10000 })
删除数据
remove = (id:number) => {
if(this.db){
let request = this.db.transaction([this.tableName], 'readwrite')
.objectStore(this.tableName)
.delete(id);
request.onsuccess = function (event) {
console.log('数据删除成功');
};
}
}
在界面初始化时加载数据
useEffect(() => {
const initPathList = async() =>{
try{
await myIndexDB.openDB();
await myIndexDB.readAll();
setNode({ posX: -1, posY: -1, ctrPosX: -1, ctrPosY: -1});//加载结束后重新渲染页面
console.log('加载数据结束');
}catch(err){
console.log('加载失败');
}
}
initPathList();
}, [])