1. 什么是indexedDB
在浏览器中常见存储方式分了几种
Local stroage
Session stroage
Cookie
indexedDB
local Stroage
按浏览器版本以及内核大小不一样可存储最大 5MB - 10MB; 通常用于存储用户数据 无时效性
localStorage.getItem(key) localStorage.setItem(key,value)
Session Stroage
按浏览器版本以及内核大小不一样可存储最大 5MB - 10MB; 通常用于存储一次性数据 网页关闭即清除
sessionStorage.getItem(key) sessionStorage.setItem(key,value)
Cookie
存储最大4KB; 通常用于存储跟踪用户的数据 无时效性 同域名下共享 使用麻烦这里推荐用插件
js-cookieimport Cookies from 'js-cookie' Cookies.get(key) Cookies.set(key,value)理解为浏览器给你提供的一个本地数据库, IndexedDB采用主键方式存储 是异步操作 避免造成浏览器假死, 无时效性 可存储大于250MB 主要取决于你电脑剩下多少空间, 可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)
下面是兼容性
2. indexedDB如何使用
打开数据库建立数据库
建立数据库使用方法 indexedDB.open(数据库名,数据库版本号) 不存在则会自动新建数据库,新建数据库时,默认为1;
建立后会触发三个事件
- [1] - 触发
error事件表示打开或新建失败 - [2] - 触发
success事件表示打开成功 - [3] - 触发
upgradeneeded事件新建数据库会触发 版本号升级也会触发(主要在里面进行建表删除表 添加索引)
// 兼容各种浏览器方式
const indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
const request = indexedDB.open("device", 1);
request.onerror = (() => {
console.log('数据库打开报错');
})
request.onsuccess = (() => {
console.log('数据库打开报错');
})
request.onupgradeneeded = ((event) => {
let objectStore = request.result; //获取数据库实例
const dbversion = event.target.result.version; //当前版本号
})
建立表
建立表是通过上面提到的打开数据库后的onupgradeneeded事件内进行
建立表的方法createObjectStore(表名,{ keyPath: 主键}) 主键就是表里的唯一id值,可以自定义主键值也可自动生成
createObjectStore(表名,{ autoIncrement: true }) 除了建立主键外还可以建立索引 索引通过建立表的实例进行创建
createIndex("索引名称","属性",{ unique: false }) unique判断索引值是否可以重复
request.onupgradeneeded = ((event) => {
let db = request.result; //获取数据库实例
const objectStore = db.createObjectStore('device', { keyPath: deviceId }); //创建表
objectStore.createIndex('name', 'name', { unique: false }); // 建立索引
db.deleteObjectStore('device') // 删除表
})
新增数据
新增需要新建一个事务 transaction(表名,只读(readonly) || 读写(readwrite));建好事务获取表的实例通过objectStore(表名)
表的实例上面有很多个方法 这里记录我用到的
- [ 1 ]
add()// 新增 onsuccess onerror - [ 2 ]
get()// 主键查找 onsuccess onerror - [ 3 ]
getAll()// 查询表里所有数据 onsuccess onerror - [ 4 ]
put()// 修改 onsuccess onerror - [ 5 ]
delete()// 删除 onsuccess onerror - [ 6 ]
index().get()// 索引查找 onsuccess onerror - [ 7 ]
clear()//清空表
request.onsuccess = ((event) => {
const db = event.target.result;
const cameraDeviceTable = db.transaction(['cameraDevice'], 'readwrite').objectStore('cameraDevice')
cameraDeviceTable.add({
deviceName: "成都匝道摄像头",
deviceId: 888,
status: 1111
})
})
查找表数据
request.onsuccess = ((event) => {
const db = event.target.result;
const cameraDeviceTable = db.transaction(['cameraDevice'], 'readonly').objectStore('cameraDevice');
let request;
// request =cameraDeviceTable.getAll(); // 查询所有数据
// request = cameraDeviceTable.get('354t6-45465-4646') // 主键id查询
request = cameraDeviceTable.index("deviceName").get("XXX摄像头") // 索引查询
request.onsuccess = (event) => {
console.log(request.result, "操作成功");
};
// 操作失败
request.onerror = (event) => {
console.log("操作失败");
};
})
修改表数据
request.onsuccess = ((event) => {
const db = event.target.result;
const cameraDeviceTable = db.transaction(['cameraDevice'], 'readwrite').objectStore('cameraDevice');
let request;
// request = cameraDeviceTable.get("354t6-45465-4646') // 主键id查询
request = cameraDeviceTable.index("deviceName").get("XXX摄像头") // 索引查询
request.onsuccess = (event) => {
let data = event.target.result
data.deviceName = '二楼厕所门口摄像头'
cameraDeviceTable.put(data)
console.log("操作成功");
};
// 操作失败
request.onerror = (event) => {
console.log("操作失败");
};
})
删除表数据
request.onsuccess = ((event) => {
const db = event.target.result;
const cameraDeviceTable = db.transaction(['cameraDevice'], 'readwrite').objectStore('cameraDevice');
let request = cameraDeviceTable.delete('354t6-45465-4646') // 主键id删除
request.onsuccess = (event) => {
console.log("操作成功");
};
// 操作失败
request.onerror = (event) => {
console.log("操作失败");
};
})
数据库链接关闭 db.close()
3. 怎么封装indexedD
新建indexedDB.js文件 封装转载于点击查看 建议看他的原文我这个是基于他上面进行了一些修改
// 适配不同浏览器
const indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
// 新建类
class IndexedDBCache {
constructor(_dbName) {
this._db = null; // 数据库
this._transactionRead = null; // 读取事务
this._transactionWrite = null, // 写入事务
this._request = null;
this._dbName = _dbName; //数据库名
this._dbversion = 1; //数据库版本
}
initDB(tableData) {
return new Promise((resolve, reject) => {
// 已打开过数据库 再次调用则为更新表
const indexedDBVersion = JSON.parse(localStorage.getItem("indexedDBVersion")) || []
let dbNameVersion = this._dbversio;
if (indexedDBVersion && indexedDBVersion.length) {
let idata = indexedDBVersion.find((i) => i.dbName == this._dbName)?.version;
if (idata) {
dbNameVersion = idata
}
}
if (this._request) {
this._db.close();
this._request = null;
this._request = indexedDB.open(this._dbName, dbNameVersion); // 打开数据库
} else {
this._request = indexedDB.open(this._dbName, dbNameVersion); // 打开数据库
}
// 数据库初始化成功
this._request.onsuccess = (event) => {
// 版本号+1 为了下次重新initDB使用
const version = Number(event.target.result.version) + 1;
if (indexedDBVersion && indexedDBVersion.length) {
const index = indexedDBVersion.findIndex((i) => i.dbName == this._dbName);
if (index != -1) {
indexedDBVersion[index].version = version;
} else {
indexedDBVersion.push({ dbName: this._dbName, version: version });
}
} else {
indexedDBVersion = [{ dbName: this._dbName, version: version }]
}
localStorage.setItem("indexedDBVersion", JSON.stringify(indexedDBVersion));
this._db = this._request.result;
console.log("数据库链接成功!")
resolve(event);
};
// 数据库初始化失败
this._request.onerror = (event) => {
reject(event);
};
// 数据库初次创建或更新时会触发
this._request.onupgradeneeded = (event) => {
const db = this._request.result;
if (tableData && tableData.length) {
tableData.forEach((i) => {
// 判断表是否存在创建表
if (!db.objectStoreNames.contains(i.tableName)) {
let storeOptions = "id" in i ? {
keyPath: i.id
} : {
keyPath: i.id,
autoIncrement: true
};
const objectStore = db.createObjectStore(i.tableName, storeOptions);
// 设置索引
if (i.indexList && i.indexList.length) {
i.indexList.forEach((j) => {
objectStore.createIndex(j)
})
}
}
})
}
resolve(event);
};
});
}
/**
* 通过表名存储新数据
* @param {String} tableName 表名
* @param {Array | Object} dataList 要存储的数据
* @returns
*/
addData(tableName, dataList) {
return new Promise((resolve, reject) => {
const transaction = this._db.transaction(tableName, "readwrite");
const objectStore = transaction.objectStore(tableName);
// 判断需存储类型 分类型存储
if (dataList?.constructor === Array) {
dataList.forEach((i) => {
var addRequest = objectStore.add(i);
addRequest.onerror = (event) => {
console.log("操作失败");
reject(event);
};
})
} else {
var addRequest = objectStore.add(dataList);
addRequest.onerror = (event) => {
console.log("操作失败");
reject(event);
};
}
transaction.oncomplete = ((event) => {
console.log("操作成功");
resolve(event);
})
})
}
/**
* 通过主键读取数据
* @param {string} key 要读取的主键值
* @returns
*/
getDataByKey(tableName, key) {
return new Promise((resolve, reject) => {
const transaction = this._db.transaction(tableName, "readonly");
const objectStore = transaction.objectStore(tableName);
// 通过主键读取数据 有主键则为主键无则返回所有数据
let request;
if (key === undefined) {
request = objectStore.getAll();
} else {
/*
objectStore.get(值) 主键查询
objectStore.index(索引).get(值) 索引查询
*/
request = objectStore.get(key);
}
// 操作成功
request.onsuccess = () => {
console.log("操作成功");
resolve(request.result);
};
// 操作失败
request.onerror = (event) => {
console.log("操作失败");
reject(event);
};
});
}
/**
* 清空表数据
* @param {string} tableName 表名
* @returns
*/
clearDBTable(tableName) {
return new Promise((resolve, reject) => {
const transaction = this._db && this._db.transaction(tableName, "readwrite");
const store = transaction && transaction.objectStore(tableName);
const response = store && store.clear();
// 操作成功
response.onsuccss = (event) => {
console.log("清空数据库数据");
resolve(event);
};
// 操作失败
response.onerror = (event) => {
reject(event);
};
});
}
/**
* 更新表里的数据
* @param {string} tableName 表名
* @param {string | Object} keyData xxx || { keys:'xx' value:'xx' } 获取数据方式
* @param {Array | Object} newData 要存储的数据
*
*/
updateTableData(tableName, keyData, newData) {
return new Promise((resolve, reject) => {
const transaction = this._db.transaction(tableName, "readwrite");
const objectStore = transaction.objectStore(tableName);
let request;
if (keyData?.constructor === String) {
request = objectStore.get(keyData);
} else {
request = objectStore.index(keyData.keys).get(keyData.value);
}
request.onsuccess = (event) => {
let data = newData;
objectStore.put(data);
transaction.oncomplete = function (event) {
resolve(event.target.result);
};
}
request.onerror = (event) => {
console.log("更新数据失败")
reject(event);
};
})
}
/**
* 通过主键删除表里的某一条数据
* @param {string} tableName 表名
* @param key 主键
*/
delteTableData(tableName, key) {
return new Promise((resolve, reject) => {
const transaction = this._db.transaction(tableName, "readwrite");
const objectStore = transaction.objectStore(tableName);
let request = objectStore.delete(key);
request.onsuccess = (event) => {
resolve(event);
}
request.onerror = (event) => {
console.log("更新数据失败")
reject(event);
};
})
}
// 关闭数据库链接
closeDB() {
this._db.close();
console.log(`关闭数据库`);
}
}
export default IndexedDBCache
4. 总结
记录项目中的第三个学习知识点... 以上记录只是我了解的还有很多API我是不了解以及没有写出来的 你们感兴趣的可以自己去看官网。