1. 程式人生 > >移動端H5的資料庫,IndexDB和WebSql

移動端H5的資料庫,IndexDB和WebSql


本篇封裝了移動端H5的資料庫,相容了IndexDB和WebSql,只需使用key-vale的方式進行存取; 

為什麼要封裝WebSql呢?ios9還不支援IndexDB;閒話少說,直接上程式碼

var isIOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);//判斷是否是ios
var isoVersion = navigator.userAgent.match(/(iPhone\sOS)\s([\d_]+)/)[2].replace(/_/g, '.');//取出ios版本號
var DB = {
        dbName:"cmpDB",
        slqVersion:(isIOS && isoVersion.split(".")[0] > 9)?"1.0":"1",//websql的版本號,由於ios的問題,版本號的寫法不一樣
        dbVersion:1,//indexDB的版本號
        storeName:"cmpStore",//store----即“表”的名字
        indexedDB:window.indexedDB || window.webkitIndexedDB, //監聽IndexDB
        db:{}, //快取資料庫,避免同一個頁面重複建立和銷燬
        store:null,
        errorCode:{   //錯誤碼
            open:91001, //開啟資料庫失敗的錯誤
            save:91002, //儲存資料失敗的錯誤
            get:91003,  //獲取資料失敗的錯誤
            delete:91004, //刪除資料失敗的錯誤
            deleteAll:91005 //清空資料庫失敗的錯誤
        },
        createStore:function(dbName,callback){//建立“表”
            var txn, store;
            if(DB.indexedDB){ //如果是支援IndexDB的
                txn = DB.db[dbName].transaction(DB.storeName, "readwrite"); //IndexDB的讀寫許可權
                store = txn.objectStore(DB.storeName);
            }else {   //如果不支援IndexDB 則使用websql
                store = DB.db[dbName].transaction(function (tx) {
                    tx.executeSql('create table if not exists '+DB.storeName+' (key text, value text null)',[],function(ts,result){
                        callback && callback()
                    });
                });
            }
            return store;
        },
        open:function(callback,dbName){ //開啟資料庫
            if(DB.indexedDB){ //如果支援IndexDB
                if(!DB.db[dbName]){//如果快取中沒有,則進行資料庫的建立或開啟,提高效率
                    var request = DB.indexedDB.open(dbName,DB.dbVersion);
                    request.onerror = function(e){
                        callback({code:DB.errorCode.open,error:e});
                    };
                    request.onsuccess = function(e){
                        if(!DB.db[dbName]){
                            DB.db[dbName] = e.target.result;
                        }
                        var store = DB.createStore(dbName);
                        callback(store);
                    };
                    request.onupgradeneeded = function(e){
                        DB.db[dbName] = e.target.result;
                        var store = DB.db[dbName].createObjectStore(DB.storeName, { keyPath: "key"});
                        callback(store);
                    }
                }else {//如果快取中已經打開了資料庫,就直接使用
                    var store = DB.createStore(dbName);
                    callback(store);
                }
            }else{
                if(!DB.db[dbName]){
                    DB.db[dbName] = openDatabase(dbName, DB.slqVersion, 'websqlDBl', 30 * 1024 * 1024);
                }
                DB.createStore(dbName,callback);
            }
        },
        save:function(key,value,callback){//儲存資料到資料庫  key---資料key  value----資料值  callback----回撥函式
            var dbName = DB.dbName;
            if(DB.indexedDB){
                var inData = {
                    key:key,
                    value:value
                };
                DB.open(function(result){
                    var error = result.hasOwnProperty("error");
                    if(error){
                        callback && callback(result);
                    }else {
                        var request =  result.put(inData);
                        request.onsuccess = function(e){
                            callback && callback({success:true});//儲存成功有success 欄位
                        };
                        request.onerror = function(e){
                            callback && callback({code:DB.errorCode.save,error:e});
                        }
                    }
                },dbName);
            }else {
                value = JSON.stringify(value); //由於websql只能存字串,所有將資料轉成json字串
                DB._websqldelete(key,function(result){ //存之前,先刪除可能存在的key值
                    if(result.hasOwnProperty("error")){
                        callback(result);
                    }else {
                        DB.db[dbName].transaction(function (ts) {
                            ts.executeSql("insert into "+DB.storeName+"(key,value) values(?,?) ", [key,value], function (ts, result) {
                                callback && callback({success:true});
                            }, function (ts, e) {
                                callback && callback({code:DB.errorCode.save,error:e});
                            });
                        });
                    }
                },dbName);

            }
        },
        get:function(key,callback){//根據key獲取值
            var dbName = DB.dbName;
            if(DB.indexedDB){
                DB.open(function(result){
                    var error = result.hasOwnProperty("error");//判斷返回的資料中是否有error欄位
                    if(error){
                        callback(result);
                    }else {
                        var request = result.get(key);
                        request.onsuccess = function(e){
                            var data = e.target.result?e.target.result.value:undefined;
                            callback({data:data,success:true});
                        };
                        request.onerror = function(e){
                            callback({code:DB.errorCode.get,error:e});
                        }
                    }
                },dbName);
            }else {
                DB.open(function(){
                    DB.db[dbName].transaction(function (ts) {
                        ts.executeSql("select * from "+DB.storeName+" where key=? ", [key], function (ts, result) {
                            var data;
                            if (result) {
                                for (var i = 0; i < result.rows.length; i++) {
                                    data = result.rows.item(i)
                                }
                                if(data) {
                                    data = data.value;
                                    try{
                                        data = JSON.parse(data);//由於存的時候是轉成json字串,所以取得時候需要解析json
                                    }catch (e){}
                                }
                            }
                            callback({data:data,success:true});

                        }, function (ts, e) {
                            callback({code:DB.errorCode.get,error:e});
                        });
                    });
                },dbName);

            }

        },
        delete:function(key,callback){  //根據key刪除某條資料
            var dbName = DB.dbName;
            if(DB.indexedDB){
                DB.open(function(result){
                    var error = result.hasOwnProperty("error");
                    if(error){
                        callback && callback(result);
                    }else {
                        var request = result.get(key);
                        request.onsuccess = function(e){
                            var recode = e.target.result;
                            if(recode){
                                request = result.delete(key);
                            }
                            callback && callback({success:true});
                        };
                        request.onerror = function (e) {
                            callback && callback({code:DB.errorCode.delete,error:e});
                        };
                    }
                },dbName);
            }else {
                DB._websqldelete(key,callback,dbName);//使用websql的方式刪除
            }

        },
        deleteAll:function(callback){//清空資料庫
            var dbName = DB.dbName;
            if(DB.indexedDB){
                DB.open(function(result){
                    var error = result.hasOwnProperty("error");
                    if(error){
                        callback && callback(result);
                    }else {
                        result.clear();
                        callback && callback({success:true});
                    }
                },dbName);
            }else {
                DB.open(function(){
                    DB.db[dbName].transaction(function (ts) {
                        ts.executeSql("delete from "+DB.storeName+"",[] ,function (ts, result) {
                            callback && callback({success:true});
                        }, function (ts, e) {
                            callback && callback({code:DB.errorCode.deleteAll,error:e});
                        });
                    });
                },dbName);

            }
        },
        _websqldelete:function(key,callback,dbName){ //私有方法,用於websql的刪除
            DB.open(function(){
                DB.db[dbName].transaction(function (ts) {
                    ts.executeSql("delete from "+DB.storeName+" where key = ? ", [key], function (ts, result) {
                        callback && callback({success:true});
                    }, function (ts, e) {
                        callback && callback({code:DB.errorCode.delete,error:e});
                    });
                });
            },dbName);        }
    };


呼叫方式

var data = {"theme":"移動開發","title":"H5資料庫封裝"}; //將被存的資料,也可以字串
var key = "oneNewData"; //存資料的key值


存資料

DB.save(key,data,function(result){
    if(result.success){
        //儲存資料成功
    }else {
       //儲存資料失敗,根據result.code來判斷是什麼原因儲存失敗了
    }

})


取資料

DB.get(key,function(result){
    if(result.success){
            var getedData = result.data; //取出資料
            //getedData = {"theme":"移動開發","title":"H5資料庫封裝"}
    }else {
           //獲取資料失敗,根據result.code來判斷是什麼原因獲取失敗了
    }
});


刪除資料

DB.delete(key,function(result){
    if(result.success){
       //刪除資料庫成功
    }else {
       //刪除資料失敗,根據result.code來判斷是什麼原因刪除失敗了
    }
});

清空資料

DB.deleteAll(function(result){
    if(result.success){
       //清空資料庫成功
    }else {
       //清空資料失敗,根據result.code來判斷是什麼原因清空失敗了
    }
});