資料庫是屬於伺服器的,這是天經地義的事,但是有時候資料也許並非需要儲存在伺服器,但是這些資料也是一條一條的記錄,怎麼辦?今天來帶領你來領略H5的一個新特性--indexedDB的風騷。你會情不自禁的發出感嘆--不可思議!
indexedDB沒有建立資料庫的概念,你可以直接連結資料庫,如果你連結的資料庫不存在,那麼會自動的建立一個資料庫。看下面的這個例子。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><button type="" id='conbtn'>链接数据库</button><script>// In the following line, you should include the prefixes of implementations you want to test. window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; // DON'T use "var indexedDB = ..." if you're not in a function. // Moreover, you may need references to some window.IDB* objects: window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange // (Mozilla has never prefixed these objects, so we don't need window.mozIDB*) function connectDB(name,version,success,error){ let dbConnect = indexedDB.open(name,version); dbConnect.onsuccess = function(e){ console.log('数据库链接成功!'); success(e.target.result); } dbConnect.onerror = function(e){ console.log('数据库链接失败!'); error(e); } dbConnect.onupgradeneeded = function(e){ success(e.target.result); let oldVersion = e.oldVersion; let newVersion = e.newVersion; console.log('数据库更新成功,旧的版本号为:'+oldVersion+",新的版本号为:"+newVersion); } } window.onload=function(){ let btn = document.getElementById('conbtn'); btn.onclick = function(){ connectDB('haha',1,function(){ console.log('链接成功,或者更新成功回调函数'); },function(){ console.log('链接失败回调函数!') }); } }</script></body></html>
我點了兩次連結資料庫,結果是這樣的。
在Application的indexedDB中我們發現多了一個東西。
可以看到haha資料庫已經成功建立了。
indexedDB的open方法用來連結或更新資料庫,第一次建立也認為是一次更新。第一個參數是資料庫的名字,第二個參數為版本號。第一次建立或版本號改變時出發更新事件upgradeneeded,連結成功後出發success事件,連結出錯時觸發error事件。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><button type="" id='conbtn'>链接数据库</button><script>// In the following line, you should include the prefixes of implementations you want to test. window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; // DON'T use "var indexedDB = ..." if you're not in a function. // Moreover, you may need references to some window.IDB* objects: window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange // (Mozilla has never prefixed these objects, so we don't need window.mozIDB*) function connectDB(name,version,success,update,error){ let dbConnect = indexedDB.open(name,version); dbConnect.onsuccess = function(e){ console.log('数据库链接成功!'); success(e.target.result); } dbConnect.onerror = function(e){ console.log('数据库链接失败!'); error(e); } dbConnect.onupgradeneeded = function(e){ update(e.target.result); let oldVersion = e.oldVersion; let newVersion = e.newVersion; console.log('数据库更新成功,旧的版本号为:'+oldVersion+",新的版本号为:"+newVersion); } } function createTable(idb,storeName,key,idxs){if(!idb){ console.log(idb);return ; }if(!key || !idxs){ console.log('参数错误');return ; }if(!storeName){ console.log('storeName必须');return ; }try{var store = idb.createObjectStore(storeName,key); console.log('数据库存储对象(table)创建成功');for(var i = 0;i<idxs.length;i++){var idx = idxs[i]; store.createIndex(idx.indexName,idx.keyPath,idx.optionalParameters); console.log('索引'+idx.indexName+'创建成功'); } }catch(e){ console.log('建表出现错误'); console.log(JSON.stringify(e)) } } window.onload=function(){ let btn = document.getElementById('conbtn'); btn.onclick = function(){ connectDB('haha',1, function(idb){ console.log('链接成功,或者更新成功回调函数'); },function(idb){ createTable(idb,'test',{keyPath:'id',autoIncrement:true},[ { indexName:'testIndex', keyPath:'name', optionalParameters:{ unique:true, multiEntry:false }}]); },function(){ console.log('链接失败回调函数!') }); } }</script></body></html>
我點了一下按鈕結果時這樣的。
這裡用到的兩個核心方法時createObjectStore,和createIndex,這兩個方法必須在資料庫發生更新的事件中執行。
createObjectStore方法可以理解成是創建表,接受第一個參數為一個字串,表示表名,第二個參數是一個對象,指定主鍵相關的東西,{keyPath:'主鍵是哪個字段',autoIncrement:是否自增}。
createIndex方法是建立索引的,接受三個參數,第一個是字串,表示索引的名字,第二個參數表示欄位名稱(誰的索引),第三個參數是個對象,具體自己查去。索引的作用是在查詢操作時可以用到,不詳講,自行google吧。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><button type="" id='conbtn'>链接数据库</button><button type="" id='add'>添加数据</button><script>// In the following line, you should include the prefixes of implementations you want to test. window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; // DON'T use "var indexedDB = ..." if you're not in a function. // Moreover, you may need references to some window.IDB* objects: window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange // (Mozilla has never prefixed these objects, so we don't need window.mozIDB*) function connectDB(name,version,success,update,error){ let dbConnect = indexedDB.open(name,version); dbConnect.onsuccess = function(e){ console.log('数据库链接成功!'); success(e.target.result); } dbConnect.onerror = function(e){ console.log('数据库链接失败!'); error(e); } dbConnect.onupgradeneeded = function(e){ update(e.target.result); let oldVersion = e.oldVersion; let newVersion = e.newVersion; console.log('数据库更新成功,旧的版本号为:'+oldVersion+",新的版本号为:"+newVersion); } } function createTable(idb,storeName,key,idxs){if(!idb){ console.log(idb);return ; }if(!key || !idxs){ console.log('参数错误');return ; }if(!storeName){ console.log('storeName必须');return ; }try{var store = idb.createObjectStore(storeName,key); console.log('数据库存储对象(table)创建成功');for(var i = 0;i<idxs.length;i++){var idx = idxs[i]; store.createIndex(idx.indexName,idx.keyPath,idx.optionalParameters); console.log('索引'+idx.indexName+'创建成功'); } }catch(e){ console.log('建表出现错误'); console.log(JSON.stringify(e)) } }function add(storeName,values){ connectDB('haha',1,function(idb){var ts = idb.transaction(storeName,"readwrite");var store = ts.objectStore(storeName); for(var i = 0;i<values.length;i++){ (function(i){var value = values[i];var req = store.put(value); req.onsuccess = function(){ console.log("添加第"+i+"个数据成功"); } req.onerror = function(e){ console.log("添加第"+i+"个数据失败"); console.log(JSON.stringify(e)); } })(i) } ts.oncomplete = function(){ console.log('添加数据事务结束!'); } },function(){},function(){}); } window.onload=function(){ let btn = document.getElementById('conbtn'); btn.onclick = function(){ connectDB('haha',1, function(idb){ console.log('链接成功,或者更新成功回调函数'); },function(idb){ createTable(idb,'test',{keyPath:'id',autoIncrement:true},[ { indexName:'testIndex', keyPath:'name', optionalParameters:{ unique:true, multiEntry:false }}]); },function(){ console.log('链接失败回调函数!') }); } let add1 = document.getElementById('add'); add1.onclick = function(){ add('test',[{name:"fjidfji",a:'uuuu'}]) } }</script></body></html>
Document链接数据库添加数据查询
# 查詢操作主要用到了遊標,這個說起來還比較多,沒時間說了,自行google。還有很多的操作這裡不講了。給一個我封裝的不是很好的簡易庫,僅供參考。
一個簡易函式庫。 ###
(function(window){'use strict'; window.dbUtil={ indexedDB :(window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB), IDBTransaction :(window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction), IDBKeyRange :(window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange), IDBCursor : (window.IDBCursor || window.webkitIDBCursor || window.msIDBCursor), idb:null, dbName:"", dbVersion:"",/** * 初始化数据库,创建表和建立链接 * @param {[type]} dbName [description] * @param {[type]} dbVersion [description] * @param {[type]} storeObjs [description] * @return {[type]} [description] */initDB:function (dbName,dbVersion,storeObjs){this.dbName = dbName;this.dbVersion = dbVersion;var dbConnect = this.indexedDB.open(this.dbName,this.dbVersion);var self = this; dbConnect.onsuccess = function(e){ self.idb = e.target.result; self.log('数据库链接成功!'); } dbConnect.onerror = function(e){ console.log(e) self.log('数据库链接失败!'); } dbConnect.onupgradeneeded = function(e){ self.idb = e.target.result;var ts = e.target.transaction;var oldVersion = e.oldVersion;var newVersion = e.newVersion; self.log('数据库更新成功,旧的版本号为:'+oldVersion+",新的版本号为:"+newVersion);if(storeObjs){for(var k = 0,len=storeObjs.length;k<len;k++){var storeObj = storeObjs[k];var storeName = storeObj.storeName;var key = storeObj.key;var idxs = storeObj.idxs; self.createTable(storeName,key,idxs) } } } },/** * 创建数据库存储对象(表) * @param {[type]} key [description] * @param {[type]} [description] * @return {[type]} [description] */createTable:function(storeName,key,idxs){var self = this;var idb = self.idb;if(!idb){ self.log('数据库没有链接');return ; }if(!key || !idxs){ self.log('参数错误');return ; }if(!storeName){ self.log('storeName必须');return ; }try{var store = idb.createObjectStore(storeName,key); self.log('数据库存储对象(table)创建成功');for(var i = 0;i<idxs.length;i++){var idx = idxs[i]; store.createIndex(idx.indexName,idx.keyPath,idx.optionalParameters); self.log('索引'+idx.indexName+'创建成功'); } }catch(e){ self.log('建表出现错误'); console.log(JSON.stringify(e)) } },/** * [add description] * @param {[type]} storeName [description] * @param {[type]} values [description] */add:function(storeName,values){var dbConnect = this.indexedDB.open(this.dbName,this.dbVersion);var self = this; dbConnect.onsuccess = function(e){var idb = e.target.result;var ts = idb.transaction(storeName,"readwrite");var store = ts.objectStore(storeName);for(var i = 0;i<values.length;i++){ (function(i){var value = values[i];var req = store.put(value); req.onsuccess = function(){ self.log("添加第"+i+"个数据成功"); } req.onerror = function(e){ self.log("添加第"+i+"个数据失败"); self.log(JSON.stringify(e)); } })(i) } ts.oncomplete = function(){ self.log('添加数据事务结束!'); } } },/** * [select description] * @param {[type]} storeName [description] * @param {[type]} count [description] * @param {Function} callback [description] * @param {[type]} indexName [description] * @return {[type]} [description] */select:function(storeName,count,callback,indexName){var dbConnect = this.indexedDB.open(this.dbName,this.dbVersion);var self = this;var total = 0;var data = []; dbConnect.onsuccess = function(e){ self.log("数据库链接成功!");var idb = e.target.result;var ts = idb.transaction(storeName,"readonly");var store = ts.objectStore(storeName);var req = store.count();var req2 = null; req.onsuccess = function(){ total = this.result;var realCount = (count<=total)?count:total;if(typeof indexName == 'undefined'){var range = IDBKeyRange.bound(0,"9999999999999999999999"); req2 = store.openCursor(range,'prev');var cc = 0; req2.onsuccess = function(){var cursor = this.result;if(total == 0){ callback([]);return; }if(cursor){ cc++; data.push(cursor.value);if(cc==realCount){ callback(data);return; } cursor.continue(); } } req2.onerror = function(){ self.log("检索出错") } }else{//待写 } } } },/** * [delete description] * @param {[type]} storeName [description] * @param {[type]} key [description] * @return {[type]} [description] */delete:function(storeName,key,callback){var dbConnect = this.indexedDB.open(this.dbName,this.dbVersion); let self = this; dbConnect.onsuccess = function(e){var idb = e.target.result;var ts = idb.transaction(storeName,'readwrite');var store = ts.objectStore(storeName); store.delete(key); self.log('删除成功!');if(callback){ callback(); } } },/** * [funciton description] * @param {[type]} storeName [description] * @param {[type]} key [description] * @param {[type]} existCall [description] * @param {[type]} notExistCall [description] * @return {[type]} [description] */isExist:function(storeName,key,existCall,notExistCall){var dbConnect = this.indexedDB.open(this.dbName,this.dbVersion); dbConnect.onsuccess = function(e){var idb = e.target.result;var ts = idb.transaction(storeName,'readonly');var store = ts.objectStore(storeName);var req = store.get(key); req.onsuccess = function(){if(this.result == undefined){ notExistCall(); }else{ existCall(this.result); } } req.onerror = function(){ notExistCall(); } } },/** * clear * @param {[type]} storeName [description] * @return {[type]} [description] */clear:function clearObjectStore(storeName){var dbConnect = this.indexedDB.open(this.dbName,this.dbVersion); dbConnect.onsuccess = function(e){var idb = e.target.result;var ts = idb.transaction(storeName,'readwrite');var store = ts.objectStore(storeName); store.clear(); } },/** * 删除数据库 * @param {[type]} dbName [description] * @return {[type]} [description] */dropDatabase:function(dbName){this.indexedDB.deleteDatabase(dbName);this.log('成功删除数据库:'+dbName); },/** * [log description] * @param {[type]} msg [description] * @return {[type]} [description] */log:function(msg){ console.log((new Date()).toTimeString()+":"+msg) } } })(window);
以上是將資料庫從伺服器移到瀏覽器--indexedDB基本操作封裝的詳細內容。更多資訊請關注PHP中文網其他相關文章!