IndexedDB 是一个基于 JavaScript 的面向对象的事务型数据库。有了 LocalStorage
和 Cookies
,为何还要推出 indexedDB
呢?其实对于在浏览器里存储数据,可使用 cookies
或 LocalStorage
,但它们都是比较简单的技术,而 IndexedDB
提供了相似数据库风格的数据存储和使用方式。javascript
LocalStorage
是用 key-value
键值模式存储数据,它存储的数据都是字符串形式。若是你想让 LocalStorage
存储对象,你须要借助 JSON.stringify()
能将对象变成字符串形式,再用 JSON.parse()
将字符串还原成对象,就是专门为小数量数据设计的,因此它的 api 设计为同步的。html
IndexedDB
很适合存储大量数据,它的 API 是异步调用的。IndexedDB
使用索引存储数据,各类数据库操做放在事务中执行。IndexedDB
甚至还支持简单的数据类型。IndexedDB
比 localstorage
强大得多,但它的 API 也相对复杂。对于简单的数据,你应该继续使用 localstorage
,但当你但愿存储大量数据时,IndexedDB
会明显的更适合,IndexedDB
能提供你更为复杂的查询数据的方式。java
有了数据库后咱们天然但愿建立一个表用来存储数据,但 indexedDB 中没有表的概念,而是 objectStore,一个数据库中能够包含多个 objectStore,objectStore 是一个灵活的数据结构,能够存放多种类型数据。也就是说一个 objectStore 至关于一张表,里面存储的每条数据和一个键相关联。咱们可使用每条记录中的某个指定字段做为键值(keyPath),也可使用自动生成的递增数字做为键值(keyGenerator),也能够不指定。选择键的类型不一样,objectStore 能够存储的数据结构也有差别。web
在 indexedDB 中,每个对数据库操做是在一个事务的上下文中执行的。事务范围一次影响一个或多个 object stores,你经过传入一个 object store 名字的数组到建立事务范围的函数来定义。例如:db.transaction(storeName, 'readwrite'),建立事务的第二个参数是事务模式。当请求一个事务时,必须决定是按照只读仍是读写模式请求访问。ajax
对 indexedDB 数据库的每次操做,描述为经过一个请求打开数据库,访问一个 object store,再继续。IndexedDB API 天生是基于请求的,这也是 API 异步本性指示。对于你在数据库执行的每次操做,你必须首先为这个操做建立一个请求。当请求完成,你能够响应由请求结果产生的事件和错误。数据库
在 IndexedDB 大部分操做并非咱们经常使用的调用方法,返回结果的模式,而是请求—响应的模式,所谓异步 API 是指并非这条指令执行完毕,咱们就可使用 request.result 来获取 indexedDB 对象了,就像使用 ajax 同样,语句执行完并不表明已经获取到了对象,因此咱们通常在其回调函数中处理。api
IDBFactory:数据库工厂,负责打开或者建立数据库数组
IDBIndex:数据库表的索引cookie
IDBRequest:机会是全部 indexedDB 操做的返回值,indexedDB 操做请求
var db; // 全局的indexedDB数据库实例。 //1\. 获取IDBFactory接口实例(文档地址: https://developer.mozilla.org/en-US/docs/Web/API/IDBFactory) var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB; if (!indexedDB) { console.log('你的浏览器不支持IndexedDB'); } // 2\. 经过IDBFactory接口的open方法打开一个indexedDB的数据库实例 // 第一个参数: 数据库的名字,第二个参数:数据库的版本。返回值是一个:IDBRequest实例,此实例有onerror和onsuccess事件。 var IDBOpenDBRequest = indexedDB.open('demoDB', 1); // 3\. 对打开数据库的事件进行处理 // 打开数据库成功后,自动调用onsuccess事件回调。 IDBOpenDBRequest.onsuccess = function(e) {}; // 打开数据库失败 IDBOpenDBRequest.onerror = function(e) { console.log(e.currentTarget.error.message); }; // 第一次打开成功后或者版本有变化自动执行如下事件:通常用于初始化数据库。 IDBOpenDBRequest.onupgradeneeded = function(e) { db = e.target.result; // 获取到 demoDB对应的 IDBDatabase实例,也就是咱们的数据库。 if (!db.objectStoreNames.contains(personStore)) { //若是表格不存在,建立一个新的表格(keyPath,主键 ; autoIncrement,是否自增),会返回一个对象(objectStore) // objectStore就至关于数据库中的一张表。IDBObjectStore类型。 var objectStore = db.createObjectStore(personStore, { keyPath: 'id', autoIncrement: true }); //指定能够被索引的字段,unique字段是否惟一。类型: IDBIndex objectStore.createIndex('name', 'name', { unique: true }); objectStore.createIndex('phone', 'phone', { unique: false }); } console.log('数据库版本更改成: ' + dbVersion); };
indexedDB 的增删改查的操做须要放到一个事务中进行(推荐)
// 建立一个事务,类型:IDBTransaction,文档地址: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction var transaction = db.transaction(personStore, 'readwrite'); // 经过事务来获取IDBObjectStore var store = transaction.objectStore(personStore); // 往store表中添加数据 var addPersonRequest = store.add({ name: '老马', phone: '189111833', address: 'aicoder.com' }); // 监听添加成功事件 addPersonRequest.onsuccess = function(e) { console.log(e.target.result); // 打印添加成功数据的 主键(id) }; // 监听失败事件 addPersonRequest.onerror = function(e) { console.log(e.target.error); };
// 建立一个事务,类型:IDBTransaction,文档地址: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction var transaction = db.transaction(personStore, 'readwrite'); // 经过事务来获取IDBObjectStore var store = transaction.objectStore(personStore); var person = { id: 6, name: 'lama', phone: '515154084', address: 'aicoder.com' }; // 修改或者添加数据。 第一参数是要修改的数据,第二个参数是主键(可省略) var updatePersonRequest = store.get(6); // 监听添加成功事件 updatePersonRequest.onsuccess = function(e) { // var p = e.target.result; // 要修改的原对象 store.put(person); }; // 监听失败事件 updatePersonRequest.onerror = function(e) { console.log(e.target.error); };
// 建立一个事务,类型:IDBTransaction,文档地址: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction var transaction = db.transaction(personStore, 'readwrite'); // 经过事务来获取IDBObjectStore var store = transaction.objectStore(personStore); store.delete(6).onsuccess = function(e) { console.log(删除成功!) };
// 建立一个事务,类型:IDBTransaction,文档地址: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction var transaction = db.transaction(personStore, 'readwrite'); // 经过事务来获取IDBObjectStore var store = transaction.objectStore(personStore); store.get(6).onsuccess = function(e) { console.log(删除成功!) };
var trans = db.transaction(personStore, 'readwrite'); var store = trans.objectStore(personStore); var cursorRequest = store.openCursor(); cursorRequest.onsuccess = function(e) { var cursor = e.target.result; if (cursor) { var html = template('tbTmpl', cursor.value); document.getElementById('tbd').innerHTML += html; cursor.continue(); // 游标继续往下 搜索,重复触发 onsuccess方法,若是到最后返回null } };
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="./lib/art_template.js"></script> </head> <body> <table> <tr> <td> <label for="name">用户名</label> </td> <td> <input type="text" name="name" id="name"> </td> </tr> <tr> <td> <label for="phone">电话</label> </td> <td> <input type="text" name="phone" id="phone"> </td> </tr> <tr> <td> <label for="address">地址</label> </td> <td> <input type="text" name="address" id="address"> </td> </tr> </table> <input type="button" value="添加用户" id="btnAdd" onclick="addPerson()"> <table> <thead> <tr> <th>id</th> <th>name</th> <th>address</th> <th>phone</th> <th>编辑</th> </tr> </thead> <tbody id="tbd"> </tbody> </table> <script id="tbTmpl" type="text/html">