HTML5 进阶系列:indexedDB 数据库

媒介

在 HTML5 的当地存储中,有一种叫 indexedDB 的数据库,该数据库是一种存储在客户端当地的 NoSQL 数据库,它能够存储大批的数据。从上篇:HTML5 进阶系列:web Storage ,我们晓得 web Storage 能够轻易天真的在当地存取简朴数据,然则关于大批结构化存储,indexedDB 的上风就越发显著。接下来我们来看看 indexedDB 怎样存储数据。

衔接数据库

一个网站能够有多个 indexedDB 数据库,但每一个数据库的名称是唯一的。我们须要经由过程数据库名来衔接某个详细的数据库。

var request = indexedDB.open('dbName', 1);  // 翻开 dbName 数据库
request.onerror = function(e){              // 监听衔接数据库失利时实行
    console.log('衔接数据库失利');
}
request.onsuccess = function(e){            // 监听衔接数据库胜利时实行
    console.log('衔接数据库胜利');
}

我们运用 indexedDB.open 要领来衔接数据库,该要领吸收两个参数,第一个是数据库名,第二个是数据库版本号。该要领会返回一个 IDBOpenDBRequest 对象,代表一个要求衔接数据库的要求对象。我们能够经由过程监听要求对象的 onsuccess 和 onerror 事宜来定义衔接胜利或失利需实行的要领。

由于 indexedDB API 中不允许数据库中的数据堆栈在统一版本中发生变化,所以须要在 indexedDB.open 要领中传入新的版本号来更新版本,防止在统一版本中反复修正数据库。版本号必需为整数!

var request = indexedDB.open('dbName', 2);  // 更新版本,翻开版本为2的数据库
// ...
request.onupgradeneeded = function(e){
    console.log('新数据库版本号为=' + e.newVersion);
}

我们经由过程监听要求对象的 onupgradeneeded 事宜来定义数据库版本更新时实行的要领。

封闭数据库

运用 indexedDB.open 衔接数据库胜利后会返回一个 IDBOpenDBRequest 对象,我们能够挪用该对象的 close 要领来封闭数据库。

var request = indexedDB.open('dbName', 2);
// ...
request.onsuccess = function(e){
    console.log('衔接数据库胜利');
    var db = e.target.result;
    db.close();
    console.log('数据库已封闭');
}

删除数据库


indexedDB.deleteDatabase('dbName');
console.log('数据库已删除');

建立对象堆栈

object store(对象堆栈)是 indexedDB 数据库的基本,在indexedDB 中并没有数据库表,而对象堆栈,就是相当于一个数据库表。

var request = indexedDB.open('dbName', 3);
// ...
request.onupgradeneeded = function(e){
    var db = e.target.result;
    var store = db.createObjectStore('Users', {keyPath: 'userId', autoIncrement: false});
    console.log('建立对象堆栈胜利');
}

db.createObjectStore 要领吸收两个参数,第一个为对象堆栈名,第二个参数为可选参数,值为一个js对象。该对象中的 keyPath 属性为主键,相当于数据库表中 id 为主键。autoIncrement 属性为 false,则示意主键值不自增,增添数据时需指定主键值。

注重:在数据库中,对象堆栈名不可反复,不然浏览器会报错。

建立索引

indexedDB 数据库中经由过程数据对象的某个属性来建立索引,在数据库中举行检索时,只能经由过程被设为索引的属性举行检索。

var request = indexedDB.open('dbName', 4);
// ...
request.onupgradeneeded = function(e){
    var db = e.target.result;
    var store = db.createObjectStore('newUsers', {keyPath: 'userId', autoIncrement: false});
    var idx = store.createIndex('usernameIndex','userName',{unique: false})
    console.log('建立索引胜利');
}

store.createIndex 要领吸收三个参数,第一个为索引名,第二个为数据对象的属性,上例中运用 userName 属性来建立索引,第三个参数为可选参数,值为一个js对象。该对象中的 unique 属性为 true,代表索引值不能够雷同,即两条数据的 userName 不能够雷同,为 false 则能够雷同。

基于事件

在 indexedDB 中,一切数据操纵都只能在事件中实行。衔接数据库胜利后,能够运用 IDBOpenDBRequest 对象的 transaction 要领开启只读事件或读写事件。

var request = indexedDB.open('dbName', 5);
// ...
request.onupgradeneeded = function(e){
    var db = e.target.result;
    var tx = db.transaction('Users','readonly');
    tx.oncomplete = function(e){
        console.log('事件完毕了');
    }
    tx.onabort = function(e){
        console.log('事件被中断了');
    }
}

db.transaction 要领吸收两个参数,第一个参数能够是字符串或数组,字符串时则是一个对象堆栈名,数组时则是由对象堆栈名构成的数组,transaction 能够对参数中任何一个对象堆栈举行操纵。第二个参数为事件形式,传入 readonly 时只能对对象堆栈举行读操纵,没法写操纵。能够传入 readwrite 举行读写操纵。

操纵数据

  • add() : 增添数据。吸收一个参数,为须要保留到对象堆栈中的对象。

  • put() : 增添或修正数据。吸收一个参数,为须要保留到对象堆栈中的对象。

  • get() : 猎取数据。吸收一个参数,为须要猎取数据的主键值。

  • delete() : 删除数据。吸收一个参数,为须要猎取数据的主键值。

var request = indexedDB.open('dbName', 5);
// ...
request.onsuccess = function(e){
    var db = e.target.result;
    var tx = db.transaction('Users','readwrite');
    var store = tx.objectStore('Users');
    var value = {
        'userId': 1,
        'userName': 'linxin',
        'age': 24
    }
    var req1 = store.put(value);        // 保留数据
    var req2 = store.get(1);            // 猎取索引userId为1的数据
    req2.onsuccess = function(){
        console.log(this.result.userName);    // linxin
    }
    var req3 = store.delete(1);             // 删除索引为1的数据
    req3.onsuccess = function(){
        console.log('删除数据胜利');        // 删除数据胜利
    }
}

add 和 put 的作用相似,区分在于 put 保留数据时,假如该数据的主键在数据库中已有雷同主键的时刻,则会修正数据库中对应主键的对象,而运用 add 保留数据,假如该主键已存在,则保留失利。

检索数据

上面我们晓得运用 get() 要领能够猎取数据,然则须要制订主键值。假如我们想要猎取一个区间的数据,能够运用游标。游标经由过程对象堆栈的 openCursor 要领建立并翻开。

openCursor 要领吸收两个参数,第一个是 IDBKeyRange 对象,该对象建立要领主要有以下几种:

// boundRange 示意主键值从1到10(包括1和10)的鸠合。
// 假如第三个参数为true,则示意不包括最小键值1,假如第四参数为true,则示意不包括最大键值10,默许都为false
var boundRange = IDBKeyRange.bound(1, 10, false, false);

// onlyRange 示意由一个主键值的鸠合。only() 参数则为主键值,整数范例。
var onlyRange = IDBKeyRange.only(1);

// lowerRaneg 示意大于即是1的主键值的鸠合。
// 第二个参数可选,为true则示意不包括最小主键1,false则包括,默许为false
var lowerRange = IDBKeyRange.lowerBound(1, false);

// upperRange 示意小于即是10的主键值的鸠合。
// 第二个参数可选,为true则示意不包括最大主键10,false则包括,默许为false
var upperRange = IDBKeyRange.upperBound(10, false);

openCursor 要领的第二个参数示意游标的读取方向,主要有以下几种:

  • next : 游标中的数据按主键值升序分列,主键值相称的数据都被读取

  • nextunique : 游标中的数据按主键值升序分列,主键值相称只读取第一条数据

  • prev : 游标中的数据按主键值降序分列,主键值相称的数据都被读取

  • prevunique : 游标中的数据按主键值降序分列,主键值相称只读取第一条数据

var request = indexedDB.open('dbName', 6);
// ...
request.onsuccess = function(e){
    var db = e.target.result;
    var tx = db.transaction('Users','readwrite');
    var store = tx.objectStore('Users');
    var range = IDBKeyRange.bound(1,10);
    var req = store.openCursor(range, 'next');
    req.onsuccess = function(){
        var cursor = this.result;
        if(cursor){
            console.log(cursor.value.userName);
            cursor.continue();
        }else{
            console.log('检索完毕');
        }
    }
}

当存在相符检索前提的数据时,能够经由过程 update 要领更新该数据:

cursor.updata({
    userId : cursor.key,
    userName : 'Hello',
    age : 18
});

能够经由过程 delete 要领删除该数据:

cursor.delete();

能够经由过程 continue 要领继承读取下一条数据,不然读到第一条数据以后不再继承读取:

cursor.continue();

总结

从衔接数据库,建立对象堆栈、索引,到操纵、检索数据,完成了 indexedDB 存取数据的完全流程。下面经由过程一个完全的例子来更好地控制 indexedDB 数据库。代码地点:indexedDB-demo

更多文章:lin-xin/blog

    原文作者:linshuai
    原文地址: https://segmentfault.com/a/1190000009213940
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞