【16】本地数据库indexdb

HTML5 的一个重要特性是本地数据持久性,它使用户能够在线和离线访问 Web 应用程序。IndexedDB支持本地存储大量对象,并使用健壮的数据访问机制检索数据。与 Web Storage 相比,IndexedDB 具有多个优势,其中包括索引、事务处理和健壮的查询功能。一个网站能够创建多个本地数据库,其中每个数据库都可以存放多个数据对象,一个对象中有存在多个数据集合,每个数据集合中有多个键值对。我们接下来一起学习一下关于IndexedDB的一些使用方法,包括数据的增删改查,以及索引和游标的使用方法。

创建数据库

首先我们创建一个名为testDB的数据库,之后我们的操作都是在这个数据库里面进行。open()可接受两个参数,一个为数据库名称,一个为数据库版本号,如果数据库不存在则创建。

var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;

//创建一个数据库
function createDb(){
    var res=window.indexedDB.open('testDB');
    res.onerror=function(e){
        alert("Database error:"+e.target.errorCode);
    };
    res.onsuccess=function(event){
        alert("Database Create!");
    };
}
2017-09-03_232031.png
删除数据库
//删除数据库
function deleteDataBase(){
    var deleteDb=window.indexedDB.deleteDatabase("testDB");
    deleteDb.onsuccess=function(e){
        alert("deleteDb success!");
    }
    deleteDb.onerror=function(e){
        alert("deleteDb error:"+e.target.errorCode);
    }
}
创建一个版本不同的数据库

这里有三个函数,onerror在打开或者创建数据库失败的时候执行,onsuccess在数据打开或者创建成功的时候执行,onupgradeneeded在数据库版本改变的时候执行。

//创建一个与版本号为2的数据库
function CreateVersion(){
    var res=window.indexedDB.open('testDB',2);
    res.onerror=function(e){
        alert("Database error:"+e.target.errorCode);
    };
    res.onsuccess=function(e){
        alert("Database Create!");
    };
    res.onupgradeneeded=function(e){
        alert("Database Version Changed!")
    }
}
2017-09-03_232126.png
创建一个存储对象

在这里我们创建了一个名称为students的存储对象,并且在创建的时候指定id字段作为数据存储的键值。

function createObjStore(){
    var res=indexedDB.open('testDB',3);
    res.onupgradeneeded=function(e){
        var db=e.target.result;
        if(!db.objectStoreNames.contains('students')){
            db.createObjectStore('students',{keyPath:"id"});
        }
        alert('DB version changed');
    };
}
// createDb();
// createObjStore();
2017-09-03_235053.png
增加数据

写了一个增加数据的函数,obj表示你的数据需要存储在那个存储对象中,dbname数据库名称,version数据库版本号,data要存放的数据。

function addData(obj,dbname,version,data){
    var res =indexedDB.open(dbname,version);

    res.onsuccess = function (evt) {
        var db = evt.target.result;

        //使用事务
        var store =db.transaction(obj, "readwrite").objectStore(obj);
        store.add(data);
    }
}

写到这里的时候遇到了一个错误"未捕获TypeError:无法使用indexeddb读取null的属性transaction",关于这个错误的发生,是由于不了解异步javascript,而indexedDB就是异步的,可以参考以下这篇文章。

Uncaught TypeError: Cannot read property 'transaction' of null with an indexeddb

2017-09-10_222210.png
删除数据
//删除
function deleteData(storeName){
    var req=window.indexedDB.open("testDB");
        
        req.onsuccess=function(e){
        var db=e.target.result;
        //删除id为100的学生信息
        var res=db.transaction(storeName,"readwrite").objectStore(storeName).delete("100");

        res.onsuccess=function(){
            console.log("delete success");
        }
    }
}
//deleteData("students");
更新数据
function updateData(storeName){
    var req=window.indexedDB.open("testDB");
        
        req.onsuccess=function(e){
        var db=e.target.result;
        var store=db.transaction(storeName,"readwrite").objectStore(storeName);

        //更新id为100的学生信息
        store.get("100").onsuccess=function(evt){
            var student=evt.target.result;
            student.name="newtest";
            var res=store.put(student);
            res.onsuccess=function(){
                console.log("success");
            }
        }
    }
}
//updateData("students");
2017-09-10_231151.png
创建索引

在创建索引的时候会出现创建不成功情况,索引的创建需要在创建存储对象的时候进行创建,如果先创建了存储对象,然后通过获取到对象,再进行索引创建的时候,这样是不成功的,所以在这里我们重新创建了一个名称teachers的存储对象。在这里创建了三个索引'nameIndex','idIndex','ageIndex',其中将idIndex的属性设置唯一。

//创建索引
function createIndex(){
    var req=window.indexedDB.open('testDB',7);

    req.onsuccess=function(e){
        console.log("success");
    }

    req.onupgradeneeded=function(e){
        var db=e.target.result;
        var store=db.createObjectStore("teachers",{keyPath:"id"});
        //创建索引
        store.createIndex('nameIndex','name',{unique:false});
        store.createIndex('idIndex','id',{unique:true});
        store.createIndex("ageIndex","age",{unique:false});
    }   
}

//createIndex();

//var data={"id":"0","name":"teacher0","age":"20"};
//addData("teachers","testDB",7,data);
2017-09-10_222210.png
索引查询
//根据索引查询
function findByIndex(obj,db){
    var req=window.indexedDB.open("testDB");
    req.onsuccess=function(e){
        var db=e.target.result;
        var store=db.transaction(obj).objectStore(obj);
        var index=store.index("nameIndex");
                //查询名字为“teacher0”的老师信息
        index.get("teacher0").onsuccess=function(e){
            var teacher=e.target.result;
            console.log(teacher);
        }
    }
}

//findByIndex("teachers","testDB");
2017-09-10_224012.png
游标

在这里我们利用游标来遍历数据库中存放的所有数据。

//游标
function findByCursor(stoeName){
    var req=window.indexedDB.open("testDB");
        
        req.onsuccess=function(e){
        var db=e.target.result;
        var store=db.transaction(stoeName).objectStore(stoeName);

        //打开游标
        var res=store.openCursor();
        res.onsuccess=function(evt){
            var cursor=evt.target.result;
            if(cursor){
                console.log(cursor.key,cursor.value);
                cursor.continue();
            }
        }
    }
}

// var data={"id":"1","name":"teacher1","age":"21"};
// addData("teachers","testDB",7,data);
// findByCursor("teachers");
2017-09-10_224854.png
索引和游标

利用索引和游标查询了名称叫做”teacher1“的所有老师信息。

//索引和游标的结合
function findByIndexAndCursor(storeName){
    var req=window.indexedDB.open("testDB");
        
        req.onsuccess=function(e){
        var db=e.target.result;
        var store=db.transaction(storeName).objectStore(storeName);

        var index=store.index("nameIndex");
        //打开游标
        var res=index.openCursor(IDBKeyRange.only('teacher1'));
        res.onsuccess=function(evt){
            var cursor=evt.target.result;
            if(cursor){
                console.log(cursor.key,cursor.value);
                cursor.continue();
            }
        }
    }
}

// var data={"id":"2","name":"teacher1","age":"23"};
// addData("teachers","testDB",7,data);

// findByIndexAndCursor("teachers");
2017-09-10_230237.png

参考文档:
HTML5本地存储——IndexedDB
使用 HTML5 IndexedDB API
Uncaught TypeError: Cannot read property 'transaction' of null with an indexeddb
点击查看完整代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容