html5 IndexedDB
来源:互联网 发布:2017网络最新最火的词 编辑:程序博客网 时间:2024/05/22 03:04
indexedDB类似nosql的数据库,是面向索引的数据库,相对于web storage,它为web离线存储提供大数据存储和搜索。
浏览器兼容性
使用步骤
- 打开一个数据库
- 获取数据库对象
- 通过数据库打开一个事务
- 通过事务进行数据库结构和数据的操作
操作数据之前,我们先建立一个数据库
/** * 创建数据库 */function createDB(){ var openReq = window.indexedDB.open(dbName); openReq.onerror = function(ev){ }; openReq.onsuccess = function(ev){ var db = ev.target.result ; tip.innerText = "数据库名称 : " + db.name; };}
由于indexedDB数据库兼容性还不是很好,需要为各自的对象各自浏览器加上前缀,我们 可以按下面来做统一对象
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;//indexDB对象window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction || {READ_WRITE: "readwrite"}; // 事务对象window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange; //key过滤对象
创建的同时,我也要能删除数据库,我们可以这样子删除数据库
/** * 删除数据库 */function delDB(){ var openReq = window.indexedDB.deleteDatabase(dbName); openReq.onerror = function(ev){ }; openReq.onsuccess = function(ev){ tip.innerText = "删除数据库成功"; };}
上面的操作设计到如下方法和事件
- window.indexedDB 获取数据库对象
- open(dbName,version) 打开数据,是操作整个数据库的入口,第二个参数是version(long 型),它的作用对数据库进行版本控制,若要对数据库的接口和数据进行操作,必须让version版本号大于之前操作的版本号数
indexedDB的数据库打开是异步操作,需要回调事件才确定打开接口,提供一下事件
- onerror 数据库打开失败的触发
- onsuccess 数据库打开成功触发
- onupgradeneeded version版本号和上一次操作版本号不一致触发,我们可以在里面对数据库进行数据结构和数据库进行操作,我们每次操作数据库的增删改查,都要确定version号比上次操作大,才能触发onupgradeneeded 进行数据库操作
三个事件都传事件对象到方法里面,可以通过事件对象获取数据库对象或者结果集,事务对象等等
创建好了数据库之后,我们就来创建一个存储对象,你可以理解为关系数据库中的表,那下面我建一个消费者customers的表
/** *创建一个存储对象 */function createObjectStore(){ var openReq = window.indexedDB.open(dbName,4); //只有改变版本号才能对该数据库结构和数据进行操作 openReq.onsuccess = function(ev){ tip.innerText = "创建存储对象成功"; }; openReq.onerror = function(ev){ tip.innerText = "失败"; }; openReq.onupgradeneeded = function(ev){//版本号不同调发这个回调 var db = ev.target.result ; //获取数据库对象 //创建表名和主键 var objectStore = db.createObjectStore("customers", { autoIncrement : true}); //创建存储对象,利用autoIncrement主键自动递增 //创建字段索引,索引可以用来搜索,详细看后面 objectStore.createIndex("uid","uid",{unique : true}); objectStore.createIndex("age","age",{unique : false}); objectStore.createIndex("name", "name", { unique: false }); };}
该创建步骤设计到以下方法
- createObjectStore(dbName,primaryKey) 创建一个存储对象
- createIndex(colunmName,indexName,option) 创建一个字段索引
创建primaryKey的时候有俩种方式
- 自动递增的主键策略,如{ autoIncrement : true},
- 拿索引字段中的一个不重复的索引作为主键的策略,如{ keyPath: “uid” }
俩种的区别,是在更新的时候,”1”的策略,不会更新数据,而是直接向数据库重新插入一条数据,因为主键key每次都是递增不相同。”2”的策略会直接更新数据
createIndex不需要为每个字段建立索引,只需建立你需要的索引就可以了,例如我们把下面的数据类型插到数据库中
const customerData = [ //数据类型json,可以把key理解为字段,建立索引的时候,没必要为每个字段建立索引 { uid: "aaa", name: "根子", age: 15, email: "genzi@qq.com" }, { uid: "bbb", name: "花子", age: 11, email: "mingzi@qq.com" }];/** * 添加一条数据 */function addData(){ var req = window.indexedDB.open(dbName,15); req.onupgradeneeded = function(ev){ var db = ev.target.result ; var transaction = ev.target.transaction || db.transaction(["customers"],IDBTransaction.READ_WRITE); //获取事务 transaction.oncomplete = function(ev){ tip.innerText = "添加数据成功"; }; transaction.onerror = function(ev){ }; var objectStore = transaction.objectStore("customers");//获取事务型的存储对象 for(var i in customerData){ objectStore.add(customerData[i]); } } }
就像关系行数据库一样,在索引数据库中,我们也必须要加上事务控制,避免数据操作不一致。一般读数据,用IDBTransaction.READ,而写数据,我们用IDBTransaction.READ_WRITE关键字来标志
下面我们把更新和删除也举例一下
/** * 更新一条数据 */function updateData(key,name,age,email){ var req = window.indexedDB.open(dbName,++index); req.onupgradeneeded = function(ev){ var db = ev.target.result; var transaction = ev.target.transaction || db.transaction(["customers"],IDBTransaction.READ_WRITE); var objstore = transaction.objectStore("customers"); var getReq = objstore.get(key); //通过主键直接获取一个对象 transaction.oncomplete = function(ev){ tip.innerText = "更新数据成功"; }; transaction.onerror = function(ev){ }; getReq.onsuccess = function(){ //获取数据成功 var obj = getReq.result; //获取数据对象 obj.ssn = "343tt4343" ; obj.name = name ; obj.age = age ; obj.email = email ; objstore.put(obj);//更新数据,主键策略不同,更新结果也会不同 } };}/** * 删除一条数据 */function delData(){ var req = window.indexedDB.open(dbName,++index); req.onupgradeneeded = function(ev){ var db = ev.target.result; var transaction = ev.target.transaction || db.transaction(["customers"],IDBTransaction.READ_WRITE); var objstore = transaction.objectStore("customers"); transaction.oncomplete = function(ev){ tip.innerText = "删除数据成功"; }; transaction.onerror = function(ev){ }; objstore.delete(1); }}
任何对数据库的增删改查,都需要加上事务获取事务型的存储对象,可以理解为关系型数据库中的表,先找表,再对表进行CRUD,下面来看看查询操作。
get 通过primary key来获取数据对象
/** * 更新一条数据 */function findDataByKey(key){ var req = window.indexedDB.open(dbName,++index); req.onupgradeneeded = function(ev){ var db = ev.target.result; var transaction = ev.target.transaction || db.transaction(["customers"],IDBTransaction.READ_WRITE); var objstore = transaction.objectStore("customers"); var getReq = objstore.get(key); //通过主键直接获取一个对象 getReq.onsuccess = function(){ //获取数据成功 var obj = getReq.result; //获取数据对象,auto ... } };}
openCursor 打开游标来遍历数据
/** * 遍历获取全部数据 */function retriving(){ //1.打开数据库 var req = window.indexedDB.open(dbName,++index); //2.判断成功,打开事务 req.onupgradeneeded = function(ev){ var db = ev.target.result; //获取数据库对象 var transaction = ev.target.transaction || db.transaction(["customers"],IDBTransaction.READ); //打开事务 var objstore = transaction.objectStore("customers");//获取操作存储对象 var cursor = objstore.openCursor(); //打开游标 cursor.onsuccess = function(ev){ var result = ev.target.result ; if (result) { console.log("key = " + result.key + " -- name = " + result.value.name); result.continue(); //继续遍历 } else { tip.innerText = "遍历完成"; } } }}
index 通过索引来获取对象
/** * 用index获取数据 */function findByIndex(index){ var req = window.indexedDB.open(dbName,++index); req.onupgradeneeded = function(ev){ var transaction = ev.target.transaction || db.transaction(["customers"],IDBTransaction.READ); //打开事务 var objstore = transaction.objectStore("customers");//获取操作存储对象 var item = objstore.index("name"); //通过建立的name索引来获取对象 item.get("lucy").onsuccess = function(event) {//获取匹配的一条数据 tip.innerText = "lucy's SSN is " + event.target.result.ssn; }; }}
通过index获取的数据可能不只一条数据,如果是多条数据,我们也可以继续用游标进行遍历
/** * 用indexcursor来变量列 */function retrivingByIndexCusor(){ var req = window.indexedDB.open(dbName,++index); req.onupgradeneeded = function(ev){ var transaction = ev.target.transaction || db.transaction(["customers"],IDBTransaction.READ); //打开事务 var objstore = transaction.objectStore("customers");//获取操作存储对象 var item = objstore.index("name"); item.openCursor().onsuccess = function(ev) {//打开 游标进行遍历 var cursor = ev.target.result; if (cursor) { console.log( cursor.key + ", uuid: " + cursor.value.uuid+ ", email: " + cursor.value.email); cursor.continue(); } }; }}
IDBKeyRange 用来做指定获取数据的范围,类型关系型数据中start limit处理分页的一样
/** * 利用keyRange来获取指定范围的的数据 */function useIDBKeyRange(){ var req = window.indexedDB.open(dbName,18); req.onupgradeneeded = function(ev){ var transaction = ev.target.transaction || db.transaction(["customers"],IDBTransaction.READ); //打开事务 var objstore = transaction.objectStore("customers");//获取操作存储对象 var item = objstore.index("age"); // 匹配唯一对象 //var singleKeyRange = IDBKeyRange.only(15); // 匹配age大于15的那些对象,包括age=15那个对象 //var lowerBoundKeyRange = IDBKeyRange.lowerBound(15); // 匹配age大于15的那些对象,不包括age=15那个对象 //var lower BoundOpenKeyRange = IDBKeyRange.lowerBound("Bill", true); // 匹配age小于15的那些对象,不包括age=15那个对象 var upperBoundOpenKeyRange = IDBKeyRange.upperBound(15); //匹配age在15和50中间的对象,不报错15但报错50 //var boundKeyRange = IDBKeyRange.bound(15, 50, false, true); item.openCursor(upperBoundOpenKeyRange).onsuccess = function(ev) { var cursor = ev.target.result; if (cursor) { console.log( cursor.key + ", SSN: " + cursor.value.ssn + ", email: " + cursor.value.email); cursor.continue(); } }; }}
我们还可以通过”prev”来进行排序
item.openCursor(upperBoundOpenKeyRange,"prev").onsuccess = function(ev) { //默认排序从小到大,prev能从大到小 var cursor = ev.target.result; if (cursor) { console.log( cursor.key + ", SSN: " + cursor.value.ssn + ", email: " + cursor.value.email); cursor.continue(); } };
当有age获取数据有重复的时候,例如35岁的有很多个,我们可以通过”nextunique”获取唯一的一条数据
item.openCursor(upperBoundOpenKeyRange,"nextunique").onsuccess = function(ev) { //默认排序从小到大,prev能从大到小 var cursor = ev.target.result; if (cursor) { console.log( cursor.key + ", SSN: " + cursor.value.ssn + ", email: " + cursor.value.email); cursor.continue(); } };
博客参考
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB
- HTML5 IndexedDB
- html5 IndexedDB
- html5 初试 indexedDB
- 使用 HTML5 IndexedDB API
- HTML5 indexedDB数据库
- HTML5のIndexedDB
- HTML5-indexedDB使用总结
- HTML5基础(indexedDB)
- HTML5之IndexedDB使用详解
- HTML5之IndexedDB使用详解
- HTML5之IndexedDB使用详解
- html5 IndexedDB浏览器端数据库
- html5 web IndexedDB使用详解
- html5本地存储之indexedDb
- html5存储:indexedDB数据库使用
- HTML5 进阶系列:indexedDB 数据库
- html5 indexedDB 数据库 详讲
- HTML5本地存储——IndexedDB
- Doxygen使用教程(个人总结)
- 算法训练 装箱问题(01背包)
- Android开发环境搭建
- 330. Patching Array-数组补丁|贪心算法
- HDU Ignatius and the Princess IV
- html5 IndexedDB
- PendingIntent
- [c++]c++程序设计-Y.Daniel.Liang 笔记
- 装饰模式
- Selenium初体验(基于Java)
- for循环的三个表达式
- java设计模式之代理模式 (静态&动态)
- 蛇形填数 递归
- Android网络开发之HttpURLConnection