HTML5本地存儲IndexedDB基礎(chǔ)介紹(-)-數(shù)據(jù)庫的簡單增刪改查

引用文檔:

HTML5本地存儲——IndexedDB(一:基本使用)
HTML5本地存儲——IndexedDB(二:索引)
IndexedDB API
JavaScript高級程序設(shè)計(第三版)

IndexedDB簡介:

IndexedDB是在瀏覽器中保存結(jié)構(gòu)化數(shù)據(jù)的一種數(shù)據(jù)庫,IndexedDB的思想是創(chuàng)建一套API,方便保存和讀取JavaScript對象,同時支持查詢和搜索。IndexedDB的最大特色是使用對象保存數(shù)據(jù)。一個IndexedDB數(shù)據(jù)庫,就是一組位于相同命名空間下的對象的集合。

IndexedDB打開數(shù)據(jù)庫:

  • open
    IndexedDB是一個作為API宿主的全局對象,由于IndexedDB設(shè)計的操作為異步進行,所以大多數(shù)的操作為請求操作,打開數(shù)據(jù)庫即向數(shù)據(jù)庫發(fā)送open請求,如下代碼所示,發(fā)送請求后,如果數(shù)據(jù)庫存在,就打開該數(shù)據(jù)庫,如果數(shù)據(jù)庫不存在,就創(chuàng)建并打開該數(shù)據(jù)庫,打開該數(shù)據(jù)庫成功后會返回一個IDBOpenDBRequest對象,這個對象上可以添加一系列的處理程序,如代碼中的onerror事件和onsuccess事件,在onsuccess中可以得到IDBDatabase對象。
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
var request,database;
request = indexedDB.open('test');
request.onerror = function(e){
    console.log(e.target.errorCode);
};
request.onsuccess = function(e){
    database = e.target.result;
    console.log('創(chuàng)建或打開數(shù)據(jù)庫成功') ;
}

以上代碼在控制臺中得到結(jié)果如下圖所示:


  • version
    默認情況下,IndexedDB是沒有版本號的,最好一開始為數(shù)據(jù)庫指定一個版本號,我們可以在創(chuàng)建或者打開數(shù)據(jù)庫時為其指定版本號,在上述代碼中將open函數(shù)傳入的參數(shù)更改為request = indexedDB.open('test',1);這樣就為當前數(shù)據(jù)庫設(shè)定了版本號,通過設(shè)置版本號可以知道想使用的數(shù)據(jù)庫是否設(shè)置了合適的對象存儲空間,在整個Web應(yīng)用中,隨著數(shù)據(jù)庫的更新和修改,可能會產(chǎn)生很多個不同的版本號(ps:關(guān)于版本號的用途也沒有摸索特別清楚,可以確定的是每次增加對象存儲空間都是要修改版本號的。)

IndexedDB對象存儲空間:

在建立或者打開數(shù)據(jù)庫后,我們一般的操作是建立表,向表中插入數(shù)據(jù),在IndexedDB中,用對象存儲空間ObjectStore來代替表的概念,存儲空間中的對象就相當于表中插入的數(shù)據(jù)。在上一步打開數(shù)據(jù)庫的onsuccess中我們可以獲得到IDBDatabase對象,創(chuàng)建存儲空間就是在通過該對象調(diào)用createObjectStore函數(shù)。

var data=[{ 
        id:1007, 
        name:"Byron", 
        age:24 
    },{ 
        id:1008, 
        name:"Frank", 
        age:30 
    },{ 
        id:1009, 
        name:"Aaron", 
        age:26 
    }];
var store = database.createObjectStore("students",{keyPath:"id"});
//var store = database.createObjectStore("students",{autoIncrement:true});
for(var i = 0 ; i < data.length;i++){
    request = store.add(data[i]);
    request.onerror = function(){
     console.error('數(shù)據(jù)庫中已有該數(shù)據(jù)')
    };
    request.onsuccess = function(){
     console.log('數(shù)據(jù)已存入數(shù)據(jù)庫')
    };
}

上述代碼中createObjectStore第一個參數(shù)為存儲對象空間的名字,第二個參數(shù)為存儲空間的鍵,既數(shù)據(jù)庫表中的主鍵,我們進行查找或者刪除某個對象都要通過這個鍵來查找,如果不設(shè)置存儲空間的鍵,可以如代碼注釋行一樣,設(shè)置自增類型。
API文檔中對于該參數(shù)說明如下:


在瀏覽器中顯示如下:

  • 錯誤說明

在創(chuàng)建存儲對象空間可能報如下錯誤:
Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction.報該錯誤的原因是:第一次opensuccess事件處于version_change事務(wù)中 這個時候不能createObjectStorecreateObjectStore操作要在onupgradeneeded的事件中執(zhí)行。

為對象存儲空間添加數(shù)據(jù):

創(chuàng)建存儲空間之后,可以用add()或者put()方法為其添加數(shù)據(jù),這兩個方法都接收所要保存的對象,區(qū)別之處在于,使用add()方法,遇到鍵值相同的對象會返回錯誤,而put()則不會報錯,會重寫原有對象。如下代碼使用add()方法進行數(shù)據(jù)添加,代碼中包括打開數(shù)據(jù)庫及創(chuàng)建存儲對象空間。可在控制臺中直接運行。

var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
var request,database;
var data=[{ 
    id:1007, 
    name:"Byron", 
    age:24 
},{ 
    id:1008, 
    name:"Frank", 
    age:30 
},{ 
    id:1009, 
    name:"Aaron", 
    age:26 
}];
request = indexedDB.open('test',1);
request.onerror = function(){
    console.log('error');
};
request.onsuccess = function(e){
    database = e.target.result; 
    console.log('創(chuàng)建或打開數(shù)據(jù)庫成功') ;
};
request.onupgradeneeded=function(e){
    database = e.target.result; 
    if(!database.objectStoreNames.contains("students")){
        var store = database.createObjectStore("students",{autoIncrement:true});
        for(var i = 0 ; i < data.length;i++){
            request = store.add(data[i]);
            request.onerror = function(){
             console.error('數(shù)據(jù)庫中已有該數(shù)據(jù)')
            };
            request.onsuccess = function(){
             console.log('數(shù)據(jù)已存入數(shù)據(jù)庫')
            };
        }
    }
}

事務(wù)

創(chuàng)建對象存儲空間之后,數(shù)據(jù)庫中的增刪改查都是通過事務(wù)transaction來完成的,在數(shù)據(jù)庫對象上調(diào)用transaction()方法可以創(chuàng)建事務(wù)。

var transaction= database.transaction("students",'readwrite');
transaction.objectStore("students")

如上代碼保證只加載students存儲空間的數(shù)據(jù),然后通過事務(wù)訪問該空間,對該空間中的數(shù)據(jù)進行操作,transaction()中傳入的第二個參數(shù)為對該空間操作的方式,默認為readonly只讀操作,代碼中傳入的是readwrite讀寫操作。其它可訪問MDN APIIDBTransaction

完整代碼:

該demo可在控制臺中執(zhí)行函數(shù),由于IndexedDB API的異步進行,如果所有函數(shù)同時執(zhí)行,打印出來的信息會不按說明排列,建議想測試哪個功能在控制臺中執(zhí)行即可。默認功能為建立打開數(shù)據(jù)庫、創(chuàng)建存儲空間添加數(shù)據(jù)。

demo默認執(zhí)行圖示



demo在控制臺中完整執(zhí)行圖示

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />  
    <meta name="author" content="sina_mobile">
    <meta name="format-detection" content="telephone=no" />
    <title></title>
</head>
<body>

<script>

    var myDB={
        name:'univisity',
        version:1,
        db:null,
        ojstore:{
            name:'students',//存儲空間表的名字
            keypath:'id'//主鍵
        }
    };

    var INDEXDB = {
        indexedDB:window.indexedDB||window.webkitindexedDB,
        IDBKeyRange:window.IDBKeyRange || window.webkitIDBKeyRange,//鍵范圍
        openDB:function(dbname,dbversion,callback){
            //建立或打開數(shù)據(jù)庫,建立對象存儲空間(ObjectStore)
            var self = this;
            var version = dbversion || 1;
            var request = self.indexedDB.open(dbname,version);
            request.onerror = function(e){
                console.log(e.currentTarget.error.message);
            };
            request.onsuccess = function(e){
                myDB.db = e.target.result;
                console.log('成功建立并打開數(shù)據(jù)庫:'+myDB.name+' version'+dbversion);
            };
            request.onupgradeneeded=function(e){
                var db=e.target.result,transaction= e.target.transaction,store;
                if(!db.objectStoreNames.contains(myDB.ojstore.name)){
                    //沒有該對象空間時創(chuàng)建該對象空間
                    store = db.createObjectStore(myDB.ojstore.name,{keyPath:myDB.ojstore.keypath});
                    console.log('成功建立對象存儲空間:'+myDB.ojstore.name);
                }
            }


        },
        deletedb:function(dbname){
            //刪除數(shù)據(jù)庫
            var self = this;
            self.indexedDB.deleteDatabase(dbname);
            console.log(dbname+'數(shù)據(jù)庫已刪除')
        },
        closeDB:function(db){
            //關(guān)閉數(shù)據(jù)庫
            db.close();
            console.log('數(shù)據(jù)庫已關(guān)閉')
        },
        addData:function(db,storename,data){
            //添加數(shù)據(jù),重復(fù)添加會報錯
            var store = store = db.transaction(storename,'readwrite').objectStore(storename),request;
            for(var i = 0 ; i < data.length;i++){
                request = store.add(data[i]);
                request.onerror = function(){
                    console.error('add添加數(shù)據(jù)庫中已有該數(shù)據(jù)')
                };
                request.onsuccess = function(){
                    console.log('add添加數(shù)據(jù)已存入數(shù)據(jù)庫')
                };
            }
            
        },
        putData:function(db,storename,data){
            //添加數(shù)據(jù),重復(fù)添加會更新原有數(shù)據(jù)
            var store = store = db.transaction(storename,'readwrite').objectStore(storename),request;
            for(var i = 0 ; i < data.length;i++){
                request = store.put(data[i]);
                request.onerror = function(){
                    console.error('put添加數(shù)據(jù)庫中已有該數(shù)據(jù)')
                };
                request.onsuccess = function(){
                    console.log('put添加數(shù)據(jù)已存入數(shù)據(jù)庫')
                };
            }
        },
        getDataByKey:function(db,storename,key){
            //根據(jù)存儲空間的鍵找到對應(yīng)數(shù)據(jù)
            var store = db.transaction(storename,'readwrite').objectStore(storename);
            var request = store.get(key);
            request.onerror = function(){
                console.error('getDataByKey error');
            };
            request.onsuccess = function(e){
                var result = e.target.result;
                console.log('查找數(shù)據(jù)成功')
                console.log(result);
            };
        },
        deleteData:function(db,storename,key){
            //刪除某一條記錄
            var store = store = db.transaction(storename,'readwrite').objectStore(storename);
            store.delete(key)
            console.log('已刪除存儲空間'+storename+'中'+key+'記錄');
        },
        clearData:function(db,storename){
            //刪除存儲空間全部記錄
            var store = db.transaction(storename,'readwrite').objectStore(storename);
            store.clear();
            console.log('已刪除存儲空間'+storename+'全部記錄');
        }
    }
    var students=[{ 
        id:1001, 
        name:"Byron", 
        age:24 
    },{ 
        id:1002, 
        name:"Frank", 
        age:30 
    },{ 
        id:1003, 
        name:"Aaron", 
        age:26 
    }];

    INDEXDB.openDB(myDB.name,myDB.version);
    setTimeout(function(){
        console.log('****************添加數(shù)據(jù)****************************');
        INDEXDB.addData(myDB.db,myDB.ojstore.name,students);
        // console.log('******************add重復(fù)添加**************************');
        // INDEXDB.addData(myDB.db,myDB.ojstore.name,students);
        // console.log('*******************put重復(fù)添加*************************');
        // INDEXDB.putData(myDB.db,myDB.ojstore.name,students);
        // console.log('*******************獲取數(shù)據(jù)1001*************************');
        // INDEXDB.getDataByKey(myDB.db,myDB.ojstore.name,1001);
        // console.log('******************刪除數(shù)據(jù)1001************');
        // INDEXDB.deleteData(myDB.db,myDB.ojstore.name,1001);
        // console.log('******************刪除全部數(shù)據(jù)************');
        // INDEXDB.clearData(myDB.db,myDB.ojstore.name);
        // console.log('******************關(guān)閉數(shù)據(jù)庫************');
        // INDEXDB.closeDB(myDB.db);
        // console.log('******************刪除數(shù)據(jù)庫************');
        // INDEXDB.deletedb(myDB.name);
    },800)
    </script>
</body>
</html>

下篇:HTML5本地存儲IndexedDB基礎(chǔ)介紹(二)- 游標和索引

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容