indexedDB就是一个非关系型数据库,它不需要你去写一些特定的sql语句来对数据库进行操作,因为它是nosql的,数据形式使用的是json
出现的意义
IndexedDB很适合存储大量数据,它的API是异步调用的。IndexedDB使用索引存储数据,各种数据库操作放在事务中执行。IndexedDB甚至还支持简单的数据类型。IndexedDB比localstorage强大得多,但它的API也相对复杂。对于简单的数据,你应该继续使用localstorage,但当你希望存储大量数据时,IndexedDB会明显的更适合,IndexedDB能提供你更为复杂的查询数据的方式。
indexedDB的特性
- 有了数据库后我们自然希望创建一个表用来存储数据,但indexedDB中没有表的概念,而是objectStore,一个数据库中可以包含多个objectStore,objectStore是一个灵活的数据结构,可以存放多种类型数据。也就是说一个objectStore相当于一张表,里面存储的每条数据和一个键相关联。我们可以使用每条记录中的某个指定字段作为键值(keyPath),也可以使用自动生成的递增数字作为键值(keyGenerator),也可以不指定。选择键的类型不同,objectStore可以存储的数据结构也有差异。
| 键类型 | 存储数据 |
|---|---|
| 不使用 | 任意值,但是没添加一条数据的时候需要指定键参数 |
| keyPath | 任意值,但是没添加一条数据的时候需要指定键参数 |
| keyGenerator | 任意值 |
| 都使用 | Javascript对象,如果对象中有keyPath指定的属性则不生成新的键值,如果没有自动生成递增键值,填充keyPath指定属性 |
- 事务性
在indexedDB中,每一个对数据库操作是在一个事务的上下文中执行的。事务范围一次影响一个或多个object stores,你通过传入一个object store名字的数组到创建事务范围的函数来定义。例如:db.transaction(storeName, 'readwrite'),创建事务的第二个参数是事务模式。当请求一个事务时,必须决定是按照只读还是读写模式请求访问。
- 基于请求
对indexedDB数据库的每次操作,描述为通过一个请求打开数据库,访问一个object store,再继续。IndexedDB API天生是基于请求的,这也是API异步本性指示。对于你在数据库执行的每次操作,你必须首先为这个操作创建一个请求。当请求完成,你可以响应由请求结果产生的事件和错误。
- 异步
在IndexedDB大部分操作并不是我们常用的调用方法,返回结果的模式,而是请求—响应的模式,所谓异步API是指并不是这条指令执行完毕,我们就可以使用request.result来获取indexedDB对象了,就像使用ajax一样,语句执行完并不代表已经获取到了对象,所以我们一般在其回调函数中处理。
代码示例
// 创建/更新一个数据库
let creatUpdateStore = function (name, verson = 1) {
console.log('creatUpdateStore');
// 打开数据库
let request = window.indexedDB.open(name, verson);
request.onsuccess = function (event) {
console.log('open success');
};
request.onerror = function (event) {
console.log('open fail');
};
request.onupgradeneeded = function (event) {
let db = event.target.result;
if (!db.objectStoreNames.contains(name)) {
// 创建仓库对象(创建表格)
// 这里我将主键设置为id
let objectStore = db.createObjectStore(name, {
keyPath: 'id',
autoIncrement: true
});
}
};
};
// 往数据库中加数据
let addDataStore = function (storeName, data, verson) {
console.log('addDataStore');
return new Promise((resolve, reject) => {
let databaseName = storeName;
let databaseVersion = verson || 1;
let db;
let request = indexedDB.open(databaseName, databaseVersion);
request.onsuccess = function (event) {
db = event.target.result;
db = event.target.result;
// 将数据保存到新建的对象仓库
let objectStore = db
.transaction(databaseName, 'readwrite')
.objectStore(databaseName);
if (uf.utils.typeof(data, 'array')) {
data.forEach(function (dataItem) {
// 添加一条数据
objectStore.add(dataItem);
});
resolve();
} else {
// 添加一条数据
objectStore.add(data);
resolve();
}
};
request.error = function () {
reject();
};
request.onupgradeneeded = function (event) {
let db = event.target.result;
if (!db.objectStoreNames.contains(storeName)) {
// 创建仓库对象(创建表格)
// 这里我将主键设置为id
let objectStore = db.createObjectStore(storeName, {
keyPath: 'id',
autoIncrement: true
});
}
};
});
};
// 获取数据
let getStoreData = function (name, key = 1) {
console.log('getStoreData');
return new Promise((resolve, reject) => {
let request = indexedDB.open(name);
request.onsuccess = function (event) {
let db = event.target.result;
let req;
try {
req = db
.transaction(name, 'readwrite')
.objectStore(name)
.get(key); // 这里的“1”也是主键的键值
} catch (e) {
reject('用户失败');
}
if (!req) {
return;
}
req.onsuccess = function () {
resolve(req.result)
};
req.onerror = function () {
reject('获取失败');
};
};
request.onupgradeneeded = function (event) {
let db = event.target.result;
if (!db.objectStoreNames.contains(name)) {
// 创建仓库对象(创建表格)
// 这里我将主键设置为id
let objectStore = db.createObjectStore(name, {
keyPath: 'id',
autoIncrement: true
});
}
};
});
};
// 删除数据
let delectStoreData = function (name, key) {
console.log('delectStoreData');
return new Promise((resolve, reject) => {
let databaseName = name;
let db;
let request = window.indexedDB.open(databaseName);
request.onsuccess = function (event) {
db = event.target.result;
let req = db
.transaction(databaseName, 'readwrite')
.objectStore(databaseName)
.delete(key); // 这里指定的是主键的键值
req.onsuccess = function () {
resolve('删除成功');
};
req.onerror = function () {
reject('删除失败');
};
};
});
};
// 更新
let updateStoreData = function (storeName, newData, key) {
console.log('updateStoreData');
return new Promise((resolve, reject) => {
let request = window.indexedDB.open(storeName);
let db;
request.onsuccess = function (event) {
db = event.target.result;
let transaction = db.transaction(storeName, 'readwrite');
let store = transaction.objectStore(storeName);
let storeData = store.get(key);
storeData.onsuccess = function (e) {
let data = e.target.result || {};
for (a in newData) {
data[a] = newData[a];
}
store.put(data);
resolve();
};
};
request.onupgradeneeded = function (event) {
let db = event.target.result;
if (!db.objectStoreNames.contains(storeName)) {
// 创建仓库对象(创建表格)
// 这里我将主键设置为id
let objectStore = db.createObjectStore(storeName, {
keyPath: 'id',
autoIncrement: true
});
}
};
});
};
// 遍历获取
let storeDataList = function (storeName) {
console.log('storeDataList');
return new Promise((resolve, reject) => {
let request = window.indexedDB.open(storeName);
let db;
request.onsuccess = function (event) {
db = event.target.result;
let transaction = db.transaction(storeName);
let store = transaction.objectStore(storeName);
let cursor = store.openCursor();//打开游标
let dataList = new Array();
cursor.onsuccess = function (e) {
var cursorVal = e.target.result;
if (cursorVal) {
dataList.push(cursorVal.value);
cursorVal.continue();
} else {
// 遍历结束
resolve(dataList);
}
};
};
request.onupgradeneeded = function (event) {
let db = event.target.result;
if (!db.objectStoreNames.contains(storeName)) {
// 创建仓库对象(创建表格)
// 这里我将主键设置为id
let objectStore = db.createObjectStore(storeName, {
keyPath: 'id',
autoIncrement: true
});
}
};
});
};
// 批量删除
function batchDelete(storeName, keys) {
console.log('batchDelete');
let allKeys = keys.map(item => {
item = +item;
return delectStoreData(storeName, item);
});
return allKeys;
/* Promise.all(allKeys).then(data => {
console.log(data);
resolve(data);
});*/
}