HTML5本地存储IndexedDB基础介绍(-)-数据库的简单增删改查

引用文档:

HTML5本地存储——IndexedDB(一:基本使用)
HTML5本地存储——IndexedDB(二:索引)
IndexedDB API
JavaScript高级程序设计(第三版)

IndexedDB简介:

IndexedDB是在浏览器中保存结构化数据的一种数据库,IndexedDB的思想是创建一套API,方便保存和读取JavaScript对象,同时支持查询和搜索。IndexedDB的最大特色是使用对象保存数据。一个IndexedDB数据库,就是一组位于相同命名空间下的对象的集合。

IndexedDB打开数据库:

  • open
    IndexedDB是一个作为API宿主的全局对象,由于IndexedDB设计的操作为异步进行,所以大多数的操作为请求操作,打开数据库即向数据库发送open请求,如下代码所示,发送请求后,如果数据库存在,就打开该数据库,如果数据库不存在,就创建并打开该数据库,打开该数据库成功后会返回一个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('创建或打开数据库成功') ;
}

以上代码在控制台中得到结果如下图所示:


  • version
    默认情况下,IndexedDB是没有版本号的,最好一开始为数据库指定一个版本号,我们可以在创建或者打开数据库时为其指定版本号,在上述代码中将open函数传入的参数更改为request = indexedDB.open('test',1);这样就为当前数据库设定了版本号,通过设置版本号可以知道想使用的数据库是否设置了合适的对象存储空间,在整个Web应用中,随着数据库的更新和修改,可能会产生很多个不同的版本号(ps:关于版本号的用途也没有摸索特别清楚,可以确定的是每次增加对象存储空间都是要修改版本号的。)

IndexedDB对象存储空间:

在建立或者打开数据库后,我们一般的操作是建立表,向表中插入数据,在IndexedDB中,用对象存储空间ObjectStore来代替表的概念,存储空间中的对象就相当于表中插入的数据。在上一步打开数据库的onsuccess中我们可以获得到IDBDatabase对象,创建存储空间就是在通过该对象调用createObjectStore函数。

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('数据库中已有该数据')
    };
    request.onsuccess = function(){
     console.log('数据已存入数据库')
    };
}

上述代码中createObjectStore第一个参数为存储对象空间的名字,第二个参数为存储空间的键,既数据库表中的主键,我们进行查找或者删除某个对象都要通过这个键来查找,如果不设置存储空间的键,可以如代码注释行一样,设置自增类型。
API文档中对于该参数说明如下:


在浏览器中显示如下:

  • 错误说明

在创建存储对象空间可能报如下错误:
Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction.报该错误的原因是:第一次opensuccess事件处于version_change事务中 这个时候不能createObjectStorecreateObjectStore操作要在onupgradeneeded的事件中执行。

为对象存储空间添加数据:

创建存储空间之后,可以用add()或者put()方法为其添加数据,这两个方法都接收所要保存的对象,区别之处在于,使用add()方法,遇到键值相同的对象会返回错误,而put()则不会报错,会重写原有对象。如下代码使用add()方法进行数据添加,代码中包括打开数据库及创建存储对象空间。可在控制台中直接运行。

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('创建或打开数据库成功') ;
};
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('数据库中已有该数据')
            };
            request.onsuccess = function(){
             console.log('数据已存入数据库')
            };
        }
    }
}

事务

创建对象存储空间之后,数据库中的增删改查都是通过事务transaction来完成的,在数据库对象上调用transaction()方法可以创建事务。

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

如上代码保证只加载students存储空间的数据,然后通过事务访问该空间,对该空间中的数据进行操作,transaction()中传入的第二个参数为对该空间操作的方式,默认为readonly只读操作,代码中传入的是readwrite读写操作。其它可访问MDN APIIDBTransaction

完整代码:

该demo可在控制台中执行函数,由于IndexedDB API的异步进行,如果所有函数同时执行,打印出来的信息会不按说明排列,建议想测试哪个功能在控制台中执行即可。默认功能为建立打开数据库、创建存储空间添加数据。

demo默认执行图示



demo在控制台中完整执行图示

<!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){
            //建立或打开数据库,建立对象存储空间(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('成功建立并打开数据库:'+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)){
                    //没有该对象空间时创建该对象空间
                    store = db.createObjectStore(myDB.ojstore.name,{keyPath:myDB.ojstore.keypath});
                    console.log('成功建立对象存储空间:'+myDB.ojstore.name);
                }
            }


        },
        deletedb:function(dbname){
            //删除数据库
            var self = this;
            self.indexedDB.deleteDatabase(dbname);
            console.log(dbname+'数据库已删除')
        },
        closeDB:function(db){
            //关闭数据库
            db.close();
            console.log('数据库已关闭')
        },
        addData:function(db,storename,data){
            //添加数据,重复添加会报错
            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添加数据库中已有该数据')
                };
                request.onsuccess = function(){
                    console.log('add添加数据已存入数据库')
                };
            }
            
        },
        putData:function(db,storename,data){
            //添加数据,重复添加会更新原有数据
            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添加数据库中已有该数据')
                };
                request.onsuccess = function(){
                    console.log('put添加数据已存入数据库')
                };
            }
        },
        getDataByKey:function(db,storename,key){
            //根据存储空间的键找到对应数据
            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('查找数据成功')
                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('****************添加数据****************************');
        INDEXDB.addData(myDB.db,myDB.ojstore.name,students);
        // console.log('******************add重复添加**************************');
        // INDEXDB.addData(myDB.db,myDB.ojstore.name,students);
        // console.log('*******************put重复添加*************************');
        // INDEXDB.putData(myDB.db,myDB.ojstore.name,students);
        // console.log('*******************获取数据1001*************************');
        // INDEXDB.getDataByKey(myDB.db,myDB.ojstore.name,1001);
        // console.log('******************删除数据1001************');
        // INDEXDB.deleteData(myDB.db,myDB.ojstore.name,1001);
        // console.log('******************删除全部数据************');
        // INDEXDB.clearData(myDB.db,myDB.ojstore.name);
        // console.log('******************关闭数据库************');
        // INDEXDB.closeDB(myDB.db);
        // console.log('******************删除数据库************');
        // INDEXDB.deletedb(myDB.name);
    },800)
    </script>
</body>
</html>

下篇:HTML5本地存储IndexedDB基础介绍(二)- 游标和索引

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

推荐阅读更多精彩内容