JS-indexedDB和应用 目录
文章目录
前言
- 前端数据库,
webSQL
的替代品 - 推荐腾讯的离线日志
reflow
- Tent-reflow
推荐阅读
- MDN - IndexedDB
- localForage:一个简单的 Polyfill,提供了简单的客户端数据存储的值语法。它在后台使用 IndexedDB,并在不支持 IndexedDB 的浏览器中回退到 WebSQL 或 localStorage。
- Dexie.js:IndexedDB 的包装,通过简单的语法,可以更快地进行代码开发。
- ZangoDB:类似 MongoDB 的 IndexedDB 接口,支持 MongoDB 的大多数熟悉的过滤、投影、排序、更新和聚合功能。
- JsStore:一个带有 SQL 语法的 IndexedDB 包装器。
- MiniMongo:由 localstorage 支持的客户端内存中的 mongodb,通过 http 进行服务器同步。MeteorJS 使用 MiniMongo。
- PouchDB:使用 IndexedDB 在浏览器中实现 CouchDB 的客户端。
- idb:一个微小的(?1.15k)库,大多 API 与 IndexedDB 类似,但做了一些小的改进,让数据库的可用性得到了大大的提升。
- idb-keyval:使用 IndexedDB 实现的超级简单且小巧的(~600B)基于 Promise 的键值对存储。
- sifrr-storage:一个非常小的(~2kB)基于 Promise 的客户端键值数据库。基于 IndexedDB、localStorage、WebSQL 和 Cookies 实现。它可以自动选择上述支持的数据库,并按照优先顺序使用。
- lovefield:Lovefield 是一个用于 Web App 的关系型数据库,使用 JavaScript 编写,可以在不同的浏览器环境中运行,提供了类似 SQL 的 API,速度快、安全且易用。
本地存储
localStorage
- 5MBsetItem(key, value)
orlocalStorage.key = value
getItem(key)
orlocalStorage.key, localStorage[key]
removeItem(key)
clear()
sessionStorage
indexedDB
indexedDB
indexedDB
- NoSQL
- 250MB
transaction
- event:
error, abort, complete
open
let request = window.indexedDB.open(databaseName, version);
- 返回一个
IDBRequest
对象 - 通过三个事件操作结果:
error, success, upgradeneeded
// error
request.onerror = function(event) {
console.log("error");
}
// success
let db;
request.onsuccess = function(event) {
db = request.result;
console.log('success');
}
// upgradeneeded
let db;
request.onupgradeneeded = function(event) {
db = event.target.result;
}
createObjectStore
request.onupgradeneeded = function(event) {
db = event.target.result;
let objectStore;
if(!db.objectStoreNames.contains('person')){
// 指定主键
objectStore = db.createObjectStore('person', {keyPath: 'id'});
// 自动生成主键
objectStore = db.createObjectStore('person', {autoIncrement: true});
// 新建索引 - 索引名称,索引所在属性,配置对象(是否包含重复值)
objectStore.createIndex('name', 'name', {unique: false});
}
}
- 新增
Person
的表格,主键是id
add
function add() {
let request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.add({id:1, name: 'zhangsan', age:24, email: 'fwx@gmail.com'});
request.onsuccess = function (event){
console.log('write success');
}
request.onerror = function (event){
console.log('write failed');
}
}
add();
transaction
:新建事务,指定表格名称和操作模式- 新建后,通过
objectStore
拿到对象 add
:向表格内写入记录
get
function read() {
let transaction = db.transaction(['person']);
let objectStore = transaction.objectStore('person');
let request = objectStore.get(1);
request.onerror = function (event) {
console.log('transaction failed.');
};
request.onsuccess = function (event) {
if (request.result){
console.log(`Name:${request.result.name}, Age: ${request.result.age}, Email: ${request.result.email}`);
}else{
console.log('未获取数据记录');
}
}
}
read();
get
的参数是主键的值
遍历数据
function readAll() {
let objectStore = db.transaction('person').objectStore('person');
objectStore.openCursor().onsuccess = function (event){
let cursor = event.target.result;
if (cursor) {
console.log(`ID: ${cursor.key},
Name: ${cursor.value.name},
Age: ${cursor.value.age},
Email: ${cursor.value.email}`);
cursor.continue();
}else {
console.log('没有更多数据了');
}
}
}
readAll();
openCursor()
是个异步操作,要监听success
事件
更新数据-put
function update() {
let request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.put({id:1, name: 'lisi', age: 35, email: 'fwx2@moxixii.com'});
request.onsuccess = function (event) {
console.log('success');
}
request.onerror = function (event) {
console.log('update failed');
}
}
update();
put
自动更新了主键为1
的记录
delete
function remove() {
let request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.delete(1);
request.onsuccess = function (event) {
console.log('delete it');
};
}
remove();
使用索引 - createIndex
- 索引的意义在于,可以让你搜索任意字段,也就是说从任意字段拿到数据记录。如果不建立索引,默认只能搜索主键(即从主键取值)
//对name字段建立了索引
objectStore.createIndex('name', 'name', { unique: false });
function index() {
let transaction = db.transaction(['person'], 'readonly');
let store = transaction.objectStore('person');
let index = store.index('name');
let request = index.get('lisi');
request.onsuccess = function (e) {
let result = e.target.result;
if (result){
}else{
}
}
}
应用场景
- 区块链项目,服务端只存储加密字符串:客户端(electron)需要下载大量的加密数据,然后批量解密,并且提供排序和数据流转。所以前端没数据库是不行的
- 配合Electron做一个桌面应用
- 需要存储大量数据的应用,比如图书管理系统这类的需要存储大量数据的应用,完全可以将图书信息存储在IndexedDB中
- 配和service worker构建pwa应用,用来缓存网络请求
- 离线日志:Tent-reflow