首页

当前位置:永利皇宫463登录 > 首页 > 浏览器里内置的数据库,前端的数据库【永利皇

浏览器里内置的数据库,前端的数据库【永利皇

来源:http://www.makebuLuo.com 作者:永利皇宫463登录 时间:2019-11-08 23:18

浏览器帮衬

莫不在付出Web应用程序最首要的难题是:“浏览器是还是不是协助自个儿想要做的?“即便浏览器对IndexedDB的支撑在继续抓牢,选用率实际不是我们所企望的那样普及。图3来得了caniuse.com网址的告诉,支持IndexedDB的为66%多一丢丢。最新版本的银狐,Chrome,Opera,Safar,iOS Safari,和Android完全帮助IndexedDB,Internet Explorer和Moto户田惠梨香部分扶植。纵然这一个列表的跟随者是冲动的,但它从不告知全部传说。

永利皇宫463登录 1

图3:浏览器对IndexedDB的扶助,来自caniuse.com

唯有丰盛新本子的Safari和iOS Safari 援救IndexedDB。据caniuse.com呈现,那只占大概0.01%的大千世界浏览器接收。IndexedDB不是多个您认为能够理之当然得到扶持的现世Web API,可是你将高速会那样认为。

介绍

IndexedDB正是一个数据库
其最大的表征是: 采纳对象保存数据,并不是利用表来保存数据,同一时间,它是异步的

IndexedDB vs Cookies

Cookies(小甜品)听上去很好吃,但其实并不是。每回HTTP接纳和发送都会传递Cookies数据,它会并吞额外的流量。举例,假若您有叁个10KB的Cookies数据,发送13遍号令,那么,总括就能够有100KB的数量在网络上传输。Cookies只好是字符串。浏览器里积存Cookies的半空中有限,超多客商禁绝浏览器接受Cookies。所以,库克ies只可以用来囤积一丢丢的非关键的多少。

依据需要

直至这里,有叁个屡次现身的主旨,您可能早已注意到。对数据库的每便操作,描述为经过一个伸手张开数据库,访谈一个object store,再持续。IndexedDB API天生是依照乞求的,那也是API异步天性提醒。对于你在数据库施行的历次操作,你一定要首先为这一个操作创设三个倡议。当倡议完毕,你可以响应由央浼结果发生的事件和错误。

正文达成的代码,演示了怎么样运用央浼张开数据库,创建叁个职业,读取object store的剧情,写入object store,清空object store。

indexDB.open()艺术的准则

分成二种状态:
1. 传播的数据库空头支票
当传入的数据库不设偶然,该措施就能创制三个名叫name的数据库,并展开它,那个时候,会先触发upgradeneeded事件;调用该函数会重临八个IDBRequest指标,能够在该对象上增添onsuccess事件onerror事件
注意:当张开二个不设有的数据库时会触发upgradeneeded事件,那是触发该事件的生机勃勃种门路,为何会触发该事件呢?该事件有怎么样效益?留个难点在那时候候,等会解答。

2. 传出的数据库存在
那边分为二种情状:

  • 当传入的数据仓库储存在,且version版本号与将在展开的数据库版本号也同等
    则直接展开该数据库,假如成功,则会触发onsuccess事件,失利则触发onerror事件
    注意:这里并不会接触upgradeneeded事件,为啥?留个疑问

  • 当传入的数据仓库储存在,不过传入的version版本号高于将在展开的数据库的本子号
    则直接张开该数据库,同一时候触发upgradeneeded事件,然后再触及onsuccess事件onerror事件,这里也触发了onupdateneeded事件

IndexedDB的用法

想要明白IndexedDB,最佳的法子是创建三个粗略的web应用:把你们班的上学的儿童的学号和姓名存款和储蓄在IndexedDB里。IndexedDB里提供了简短的增、删、改、查接口。

实行用户分界面特定代码

近期具备特定于数据库的代码被封装在app.db模块中,用户分界面特定代码能够行使此模块来与数据库交互作用。客商分界面特定代码的完整清单(index.ui.js)能够在清单3中得到,完整的(index.html)页面包车型客车HTML源代码能够在项目清单4中获得。

接受游标查询数据

行使工作能够直接通过 已知的键检索单个对象。而在须要找出多个对象时,则供给在作业内成立游标。

游标并不会提前采摘结果,游标先指向结果中的第大器晚成项,在吸取查找下后生可畏项的指令时,才会针对下生机勃勃项

如下:

let transaction = db.transaction('customers', 'readwrite'),
let store = transaction.objectStore('customers'),
let request = store.openCursor(null) ; // 这里创建游标
request.onsuccess = function (event) {
  // event.target.result 中保存的是在存储空间中查询到的对象
  // event.target.result 中有几个属性值,可以了解到查询到的对象中的细节,
  // key: 当前访问的对象的键
  // value:当前访问的实际对象
  // primaryKey: 游标使用的键
  // direction:数值,表示游标移动的方向
  let cursor = event.target.result;
  let value, updateRequest, deleteRequest;

  // 这里必须要检查游标中是否有数据
  if (cursor) {
    if (cursor.key === '555-55-5555') {
      value = cursor.value;   // 获取到实际的访问对象
      value.name = 'hexon';   // 修改对象的name属性
      // 调用update()方法可以用指定的对象,更新对象的value
      updateRequest = cursor.update(value);     
      updateRequest.onsuccess = function() {
          // 处理成功
       }
    }
    cursor.continue() ;  // 移动到下一项,会触发下一次请求,同时成功则触发request.onsuccess
  }
}

地点例子中,能够应用cursor.delete()措施删除当前项

IndexedDB vs Web SQL

WebSQL也是生机勃勃种在浏览器里积累数据的本事,跟IndexedDB不一样的是,IndexedDB更疑似二个NoSQL数据库,而WebSQL更疑似关系型数据库,使用SQL查询数据。W3C已经不再协助这种工夫。具体情形请看:。

因为不再援助,所以你就不要在档案的次序中选取这种手艺了。

兼备标准

IndexedDB的架构很像在黄金时代部分盛行的服务器端NOSQL数据库实现中的设计指南类型。面向对象数据通过object stores(对象饭馆卡塔尔进行持久化,全数操作基于需要同期在作业限定内实施。事件生命周期让你能够支配数据库的配置,错误通过荒诞冒泡来使用API处理。

upgradeneeded事件

触发该事件的规范:当展开的数据库不设有,恐怕传播的数据库版本version高于当前版本,则会触发该事件

upgradeneeded事件的功力:当张开了一个数据库之后,必要开辟三个名称为:对象存款和储蓄空间 的玩意(能够领略为数量就是寄放在此个空间里面,一个数据库能够创立三个目的存款和储蓄空间卡塔 尔(阿拉伯语:قطر‎,而 对象存款和储蓄空间 只能在upgradeneeded事件的管理函数中创设

接受时,注意以下二种情景:

  1. 当大家第贰次张开创设数据库时,会触发upgradeneeded事件,大家就须求在里边创造对象存款和储蓄空间

  2. 当我们对数据库版本举行更新时,也会触发该事件,当时可以在这里创制新的目的存款和储蓄空间,原来的靶子存储空间依然存在

注意:如果需求对指标存款和储蓄空间拓宽改变,那么只可以先将储存在它当中的数码读抽取来,再将其除去,然后使用新的选项去成立它,再写入原本的多寡

开垦数据库并创设对象存款和储蓄空间的代码:

// 对于该API,各浏览器还未同一,所以需要对一些接口添加前缀
window.indexedDB = window.indexedDB || window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction || {READ_WRITE: "readwrite"};
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
window.IDBCursor = window.IDBCursor || window.webkitIDBTransaction;

// 判断浏览器是否支持IndexedDB
if (!window.indexedDB) {
window.alert("Your browser doesn't support a stable version of IndexedDB.")
}

var request , db;
// 打开或创建 名为dbName的数据库
request = window.indexedDB.open('dbName', 2)
request.onsuccess = function (event) {
   db = event.target.result;
}

request.onerror = function (event) {
   console.log('错误代码: ' + event.target.errorCode);
}

request.onupgradeneeded = function(event) {
  db = event.target.result;  // 
  // 创建一个   对象存储空间,名为customers
  var objectStore = db.createObjectStore('customers', {keyPath: 'ssn'});
  // 对于某些数据,可以为一个对象存储空间指定多个键。比如,若要通过用户ID 和用户名 两种方式来保存用户资料,就需要通过两个键来存取记录
  // 因此可以使用createIndex,名字是有可能重复的,所以其unique 设置为 false ;第一个name是索引的名字,该名字是索引的名字,第二个name是索引的属性的名字,该名字要与对象中的属性相同
  objectStore.createIndex('name', 'name', { unique: false});

  // 创建一个email的索引,该email是独特的,所以 unique 设置为 true
  objectStore.createIndex('email', 'email', { unique: true});
}

IndexedDB是HTML5业内里新现身的浏览器里放置的数据库。对于在浏览器里积累数据,你能够使用cookies或local storage,但它们都以比较轻巧的技术,而IndexedDB提供了看似数据库风格的多少存款和储蓄和利用方法。存款和储蓄在IndexedDB里的多寡是永久保存,不像cookies那样只是有的时候的。IndexedDB里提供了查询数据的意义,在online和offline方式下都能应用。你可以用IndexedDB存储大型数据。

Implementing Database-Specific Code

对数据库的各类操作关联着叁个先决条件,即有三个开垦的数据库。当数据库正在被展开时,通过检查数据库版本来判断数据库是不是供给任何改动。上面包车型地铁代码彰显了模块怎样追踪当前版本,object store名、某成员(保存了纵然数据库张开央浼实现后的数据库当前实例卡塔 尔(英语:State of Qatar)。

JavaScript

version: 1, objectStoreName: 'tasks', instance: {},

1
2
3
version: 1,
objectStoreName: 'tasks',
instance: {},

在这里边,数据库张开需要产生时,模块乞求版本1数据库。要是数据库不真实,或然版本小于1,upgrade needed事件在开荒恳求完结前触发。那几个模块被设置为只行使多少个object store,所以名字直接定义在此边。最终,实例成员被创建,它用于保存风度翩翩旦展开供给实现后的数据库当前实例。

接下去的操作是落到实处upgrade needed事件的事件管理程序。在这里处,检查当前object store的名字来判定需要的object store名是不是留存,假若不设有,创建object store。

JavaScript

upgrade: function (e) { var _db = e.target.result, names = _db.objectStoreNames, name = db.objectStoreName; if (!names.contains(name)) { _db.createObjectStore( name, { keyPath: 'id', autoIncrement: true }); } },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
upgrade: function (e) {
    var
        _db = e.target.result,
        names = _db.objectStoreNames,
        name = db.objectStoreName;
    if (!names.contains(name)) {
        _db.createObjectStore(
            name,
            {
                keyPath: 'id',
                autoIncrement: true
            });
    }
},

在此个事件管理程序里,通过事件参数e.target.result来访谈数据库。当前的object store名称的列表在_db.objectStoreName的字符串数组上。以往,纵然object store一纸空文,它是经过传递object store名称和store的键的概念(自增,关联到数量的ID成员卡塔尔国来制造。

模块的下一个效果是用来捕获错误,错误在模块分化的哀告创制时冒泡。

JavaScript

errorHandler: function (error) { window.alert('error: ' + error.target.code); debugger; },

1
2
3
4
errorHandler: function (error) {
    window.alert('error: ' + error.target.code);
    debugger;
},

在那地,errorHandler在一个警报框突显任何不当。这几个函数是故意保持简单,对开荒本人,当你学习使用IndexedDB,您能够相当的轻巧地看来此外错误(当他俩发生时卡塔尔。当您考虑在生育景况使用那么些模块,您供给在这里个函数中落到实处部分错误管理代码来和你的应用程序的上下文打交道。

这两天基本功达成了,这意气风发节的别的部分将演示怎么样落到实处对数据库实行一定操作。第一个须要检查的函数是open函数。

JavaScript

open: function (callback) { var request = window.indexedDB.open( db.objectStoreName, db.version); request.onerror = db.errorHandler; request.onupgradeneeded = db.upgrade; request.onsuccess = function (e) { db.instance = request.result; db.instance.onerror = db.errorHandler; callback(); }; },

1
2
3
4
5
6
7
8
9
10
11
12
open: function (callback) {
    var request = window.indexedDB.open(
        db.objectStoreName, db.version);
    request.onerror = db.errorHandler;
    request.onupgradeneeded = db.upgrade;
    request.onsuccess = function (e) {
        db.instance = request.result;
        db.instance.onerror =
            db.errorHandler;
        callback();
    };
},

open函数试图展开数据库,然后实践回调函数,告知数据库成功张开药方可筹划利用。通过拜谒window.indexedDB调用open函数来创立张开诉求。这么些函数接受你想打开的object store的名称和你想接纳的数据库版本号。

假如乞请的实例可用,第一步要开展的做事是设置错误管理程序和升级函数。记住,当数据库被张开时,纵然脚本乞求比浏览器里更加高版本的数据库(或许生龙活虎旦数据库子虚乌有),晋级函数运转。可是,假若央求的数据库版本相配当前数据库版本同期未有不当,success事件触发。

若是全体成功,展开数据库的实例可以从呼吁实例的result属性获得,这么些实例也缓存到模块的实例属性。然后,onerror事件设置到模块的errorHandler,作为以往其余必要的大谬不然捕捉管理程序。最后,回调被施行来告诉调用者,数据库已经开荒並且正确地配备,能够选取了。

下叁个要落实的函数是helper函数,它回到所央求的object store。

JavaScript

getObjectStore: function (mode) { var txn, store; mode = mode || 'readonly'; txn = db.instance.transaction( [db.objectStoreName], mode); store = txn.objectStore( db.objectStoreName); return store; },

1
2
3
4
5
6
7
8
9
getObjectStore: function (mode) {
    var txn, store;
    mode = mode || 'readonly';
    txn = db.instance.transaction(
        [db.objectStoreName], mode);
    store = txn.objectStore(
        db.objectStoreName);
    return store;
},

在这里边,getObjectStore采纳mode参数,允许你决定store是以只读仍旧读写方式央浼。对于那一个函数,暗许mode是只读的。

种种针对object store的操作都是在二个东西的内外文中奉行的。事必须要接纳叁个object store名字的数组。那么些函数此次被布置为只行使多少个object store,然而倘使你必要在事情中操作五个object store,你供给传递四个object store的名字到数组中。事务函数的第二个参数是三个情势。

就算事情必要可用,您就足以因而传递须求的object store名字来调用objectStore函数以拿到object store实例的访谈权。这一个模块的其余函数使用getObjectStore来赢得object store的访谈权。

下四个兑现的函数是save函数,实行插入或更新操作,它依照传入的数目是不是有八个ID值。

JavaScript

save: function (data, callback) { db.open(function () { var store, request, mode = 'readwrite'; store = db.getObjectStore(mode), request = data.id ? store.put(data) : store.add(data); request.onsuccess = callback; }); },

1
2
3
4
5
6
7
8
9
10
11
12
save: function (data, callback) {
    db.open(function () {
        var store, request,
            mode = 'readwrite';
 
        store = db.getObjectStore(mode),
        request = data.id ?
            store.put(data) :
            store.add(data);
        request.onsuccess = callback;
    });
},

save函数的七个参数分别是索要保留的数码对象实例和操作成功后须要实施的回调。读写情势用于将数据写入数据库,它被盛传到getObjectStore来博取object store的二个可写实例。然后,检查数据对象的ID成员是不是留存。假如存在ID值,数据必须校勘,put函数被调用,它创设长久化哀告。否则,要是ID不设有,这是新数据,add伏乞重临。最终,不管put大概add 诉求是或不是进行了,success事件管理程序须要设置在回调函数上,来告诉调用脚本,一切进展顺遂。

下意气风发节的代码在清单1所示。getAll函数首先展开数据库和做客object store,它为store和cursor(游标卡塔 尔(阿拉伯语:قطر‎分别设置值。为数据库游标设置游标变量允许迭代object store中的数据。data变量设置为三个空数组,充作数据的容器,它回到给调用代码。

在store访谈数据时,游标遍历数据库中的每条记下,会触发onsuccess事件管理程序。当每条记下探望时,store的数据能够透过e.target.result事件参数拿到。纵然事实上数据从target.result的value属性中获得,首先须求在总计访谈value属性前确定保证result是四个可行的值。即使result存在,您能够增多result的值到数据数组,然后在result对象上调用continue函数来继承迭代object store。最终,若无reuslt了,对store数据的迭代停止,同有时候数据传递到回调,回调被推行。

近期模块能够从data store得到全数数据,下多少个内需完毕的函数是担负访谈单个记录。

JavaScript

get: function (id, callback) { id = parseInt(id); db.open(function () { var store = db.getObjectStore(), request = store.get(id); request.onsuccess = function (e){ callback(e.target.result); }; }); },

1
2
3
4
5
6
7
8
9
10
11
get: function (id, callback) {
    id = parseInt(id);
    db.open(function () {
        var
            store = db.getObjectStore(),
            request = store.get(id);
        request.onsuccess = function (e){
            callback(e.target.result);
        };
    });
},

get函数实行的率先步操作是将id参数的值调换为一个整数。决计于函数被调用时,字符串或整数都或者传递给函数。这些完结跳过了对借使所给的字符串不能够转变来整数该咋办的情事的拍卖。风姿洒脱旦四个id值准备好了,数据库张开了和object store能够访谈了。获取访谈get央求现身了。需要成功时,通过传播e.target.result来实施回调。它(e.target.result卡塔 尔(阿拉伯语:قطر‎是因而调用get函数到手的单条记录。

前日保留和筛选操作已经现身了,该模块还要求从object store移除数量。

JavaScript

'delete': function (id, callback) { id = parseInt(id); db.open(function () { var mode = 'readwrite', store, request; store = db.getObjectStore(mode); request = store.delete(id); request.onsuccess = callback; }); },

1
2
3
4
5
6
7
8
9
10
11
'delete': function (id, callback) {
    id = parseInt(id);
    db.open(function () {
        var
            mode = 'readwrite',
            store, request;
        store = db.getObjectStore(mode);
        request = store.delete(id);
        request.onsuccess = callback;
    });
},

delete函数的名目用单引号,因为delete是JavaScript的保留字。那可以由你来支配。您能够采纳命名函数为del或别的名目,不过delete用在此个模块为了API尽可能好的发布。

传递给delete函数的参数是目的的id和一个回调函数。为了保持这几个达成轻易,delete函数约定id的值为整数。您能够接收创造一个更康健的落到实处来拍卖id值不能够解析成整数的荒诞例子的回调,但为了带领原因,代码示例是画蛇著足的。

若是id值能保险转换来叁个卡尺头,数据库被张开,二个可写的object store拿到,delete函数字传送入id值被调用。当号召成功时,将实行回调函数。

在某个情形下,您只怕必要删除叁个object store的享有的笔录。在这里种地方下,您访问store同时扫除全部内容。

JavaScript

deleteAll: function (callback) { db.open(function () { var mode, store, request; mode = 'readwrite'; store = db.getObjectStore(mode); request = store.clear(); request.onsuccess = callback; }); }

1
2
3
4
5
6
7
8
9
deleteAll: function (callback) {
    db.open(function () {
        var mode, store, request;
        mode = 'readwrite';
        store = db.getObjectStore(mode);
        request = store.clear();
        request.onsuccess = callback;
    });
}

这里deleteAll函数肩负展开数据库和拜会object store的叁个可写实例。豆蔻年华旦store可用,二个新的乞请通过调用clear函数来成立。生机勃勃旦clear操作成功,回调函数被推行。

键范围

游标也得以接收四个键,也正是经过键来设定游标查找的范围;
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebStorage DEMO</title>
</head>
<body>
<div class="networkStatus">
<button class="clear">清空数据</button>
<button class="add">增加数码</button>
<button class="query">查询数据</button>
<button class="delete">删除数据</button>
<button class="cursor">使用游标查询</button>
<button class="keyRange">使用keyrange查询</button>
<button class="index">使用index</button>
</div>

<script>
let network = document.querySelector('.networkStatus'),
addBtn = document.querySelector('.add'),
queryBtn = document.querySelector('.query'),
deleteBtn = document.querySelector('.delete'),
cursorBtn = document.querySelector('.cursor'),
clearBtn = document.querySelector('.clear'),
keyRange = document.querySelector('.keyRange'),
indexBtn = document.querySelector('.index')
;

// 决断网路是还是不是在线
// if (navigator.onLine) {
// network.innerText = "网络在线";
// } else {
// network.innerText = "网络掉线";
// }

// // 监察和控制网络状态的平地风波:online 和 offline, 那多个事件在window对象上
// window.addEventListener('online', () => {
// network.innerText = "互连网在线";
// });

// window.addEventListener('offline', () => {
// network.innerText = "互联网掉线";
// });

//--------cookie的使用---------------
let CookieUtil = {
get: (name) => {
let cookieName = encodeURIComponent(name) + "=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;

  if (cookieStart > -1) {
    let cookieEnd = document.cookie.indexOf(';', cookieStart);
    if (cookieEnd === -1) {
      cookieEnd = document.cookie.length;
    }
    cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
  }

  return cookieValue;
},
set: function (name, value, expires, path, domain, secure) {
  let cookieText = encodeURIComponent(name) + '=' +
                   encodeURIComponent(value);

  if (expires instanceof Date) {
    cookieText += '; expires=' + expires.toGMTString();
  }

  if (path) {
    cookieText += '; path=' + path;
  }

  if (domain) {
    cookieText += '; domain=' + domain;
  }

  if (secure) {
    cookieText += '; secure';
  }

  document.cookie = cookieText;
},

// 删除cookie, 并没有直接的删除cookie的方法,这里通过重新设置cookie名称,来对cookie进行替换
// 同时 将过期时间expires设置为过去的时间,
unset: function(name, path, domain, secure) {
  this.set(name, '', new Date(0), path, domain, secure);
}

}

CookieUtil.set('name', 'hexon');
CookieUtil.set('book', 'Profession Javascript');

// 读取cookie的值
// console.log(CookieUtil.get('name'));
// console.log(CookieUtil.get('book'));

// 删除cookie
CookieUtil.unset('name');
CookieUtil.unset('book');

// 设置cookie, 包蕴它的路径、域、失效日期
CookieUtil.set('name', 'Hexon', 'books/projs/', 'www.wrox.com', new Date('January 1, 2017'));

// 删除刚刚安装的cookie
CookieUtil.unset('name', 'books/projs/', 'www.www.wrox.com');

// 设置安全的cookie
CookieUtil.unset('name', 'hexon', null, null, null, null, true)

// --- IndexedDB 数据库的施用
var request = window.indexedDB.open('dbName', 2)
var db;
const dbName = 'the_name';
// 创设贰个数码
const customerData = [
{ ssn: '444-44-4444', name: 'AAA', age: 35, email: 'AAA@company.com'},
{ ssn: '666-66-6666', name: 'CCC', age: 35, email: 'CCC@company.com'},
{ ssn: '777-77-7777', name: 'DDD', age: 32, email: 'DDD@home.org'},
{ ssn: '555-55-5555', name: 'BBB', age: 32, email: 'BBB@home.org'},

];

window.indexedDB = window.indexedDB || window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction || {READ_WRITE: "readwrite"};
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
window.IDBCursor = window.IDBCursor || window.webkitIDBTransaction;

if (!window.indexedDB) {
window.alert("Your browser doesn't support a stable version of IndexedDB.")
}

// 3 是自给自足的数据库版本,即使名字为MyTestDatabase的数据库海市蜃楼,就能创制该数据库,然后 onupgradeneeded 事件会被触发;
// 要是数据仓库储存在,不过对版本晋级了,也会触发onupgradeneeded事件,
// 注意:版本号是叁个 unsigned long long 类型的值,由此不要选择float,不然会将其退换为其最接近的大背头

// 生成管理程序
request.onerror = function (event) {
// do Something
alert('Database error: ' + event.target.errorCode);
};

request.onsuccess = function (event) {
// do Something
console.log('创设数据库成功');
db = event.target.result; // 创立成功后,e.target.result 中积累的是IDBDatabase对象的实例
}

// 当创建一个新的数码库 恐怕 更新已存在数据库的本子, onupgradeneeded事件将会被触发,新的对象存款和储蓄在event.target.result中。
// 在该管理程序中,数据库已经具有先前版本的靶子存储,由此不必再一次创立那一个目的存款和储蓄,只必要成立任何我们需求的靶子存款和储蓄,或然
// 从在此以前版本中去除不在须求的目的存款和储蓄。假设急需更动当前指标存款和储蓄,则必得先删除旧的靶子存款和储蓄,然后在应用新的选项成立。
// 删除旧的对象存款和储蓄,在其上的音信都会被剔除;
// 注意:该事件是唯意气风发一个能够对数据库进行操作的地点,在该事件之中,你对指标存款和储蓄举行删除、改正或移除索引
request.onupgradeneeded = function(event) {
console.log('onupgradeneeded');
var db = event.target.result;

// 创建一个   对象存储空间,名为customers
var objectStore = db.createObjectStore('customers', {keyPath: 'ssn'});
// 对于某些数据,可以为一个对象存储空间指定多个键。比如,若要通过用户ID 和用户名 两种方式来保存用户资料,就需要通过两个键来存取记录
// 因此可以使用createIndex,名字是有可能重复的,所以其unique 设置为 false ;第一个name是索引的名字,该名字是索引的名字,第二个name是索引的属性的名字,该名字要与对象中的属性相同
objectStore.createIndex('name', 'name', { unique: false});

// // 创建一个email的索引,该email是独特的,所以 unique 设置为 true
objectStore.createIndex('email', 'email', { unique: true});

}

function save(data) {
/// 对于数据库的对象存储空间中多少的读取或校订数据,都要经过事物来组织具备操作
// 最简便的创设事物的章程是:var transaction = db.transaction();
let transaction = db.transaction('customers', 'readwrite'); // 成立多少个事情,并定义该事情的操作为 “readwrite” ,并回到其索引
let store = transaction.objectStore('customers'); // 获得索引后,使用objectStore()方法并传播存款和储蓄空间的称谓,就足以访谈特定的积攒空间

for (var i in customerData) {
  let req = store.put(customerData[i]);   // 往一个存储空间中添加数据
}

transaction.oncomplete = function(event) {
  console.log(event.target);
  alert('存储数据完成');
};

transaction.onsuccess = function(event ) {
  console.log('onsuccess 事件');
}

}

function clear() {
// body...
let transaction = db.transaction('customers', 'readwrite');
let store = transaction.objectStore('customers').clear();
store.onerror = function(event) {
console.log('清空数据退步');
}
store.onsuccess = function(event) {
console.log('清空数据成功');
}
}

// 使用事务 直接通过已知的键索引 单个对象 (只可以索引单个对象卡塔尔
function getData() {
let transaction = db.transaction('customers', 'readwrite'); // 成立一个事物, 并定义该事情的操作为 "readonly"
let store = transaction.objectStore('customers').get('444-44-4444'); // 使用get() 能够博得值

store.onerror = function (event) {
  alert('did not get the object');
}

store.onsuccess = function (event) {
  var result = event.target.result;
  console.log(result);
  alert('获取数据完成! 年龄是: ' + result.age);
}

}

function deleteData() {
let transaction = db.transaction('customers', 'readwrite');
let store = transaction.objectStore('customers');
store.delete('444-44-4444');
alert('s删除数据产生');
}

// 在作行业内部创建游标查询 能够索引 多少个对象(注意: 是多少个对象卡塔 尔(英语:State of Qatar)
// 游标不提前手提式有线话机结果
function cursorQuery() {
let transaction = db.transaction('customers', 'readwrite'),
store = transaction.objectStore('customers'),
request = store.openCursor(null) ; // 这里开创游标

request.onsuccess = function (event) {

  // event.target.result 中保存的是在存储空间中查询到的对象
  // event.target.result 中有几个属性值,可以了解到查询到的对象中的细节,
  // key: 当前访问的对象的键
  // value:当前访问的实际对象
  // primaryKey: 游标使用的键
  // direction:数值,表示游标移动的方向

  let cursor = event.target.result;
  let value, updateRequest, deleteRequest;
  if (cursor) {
  //   if (cursor.key === '555-55-5555') {
  //     value = cursor.value;   // 获取到实际的访问对象
  //     value.name = 'hexon';   // 修改对象的name属性

  //     updateRequest = cursor.update(value);      // 调用update()方法可以用指定的对象,更新对象的value
  //     updateRequest.onsuccess = function() {
  //       // 处理成功
  //     }
  //     updateRequest.onerror = function() {
  //       // 处理失败
  //     }


  //     // 使用游标删除当前项
  //     // deleteRequest = cursor.delete();
  //     // deleteRequest.onsuccess = function() {
  //     //   // 删除成功处理
  //     // }
  //     // deleteRequest.onerror = function() {
  //     //   // 删除失败处理
  //     // }


  //   }
  //   console.log(event.target.result);
  // }
  console.log(cursor.value);
  cursor.continue();      // 移动到下一项,
  }
  request.onerror = function(event) {
    console.log('游标查询创建失败')
  }
}

}

// 使用keyrange查询
function keyRangeQuery() {
let transaction = db.transaction('customers', 'readwrite')
let store = transaction.objectStore('customers');
// 使用bound()方法 定义键范围
let range = IDBKeyRange.bound('555-55-5555', '777-77-7777', true, false);
// 将键传入游标创造
let request = store.openCursor(range);

request.onsuccess = function(event) {
  let cursor = event.target.result;
  if (cursor) {
    console.log('游标查询到的值' + JSON.stringify(cursor.value));
    cursor.continue()     // 移动到下一项
  }

}

request.onerror = function(event) {
  console.log("使用游标 + keyrange 查询失败")
}

}

// 使用索引
function useIndex() {
let store = db.transaction('customers').objectStore('customers'),
index = store.index('name');
request = index.openCursor();
request.onsuccess = function (event) {
let cursor = event.target.result;
if (cursor) {
console.log(cursor);
cursor.continue();
}
}
}

addBtn.addEventListener('click', function(e) {
save();
}, false);

deleteBtn.addEventListener('click', function(e) {
deleteData();
}, false);

queryBtn.addEventListener('click', function(e) {
getData();
}, false);

cursorBtn.addEventListener('click', function(e) {
cursorQuery();
}, false);

clearBtn.addEventListener('click', function(e) {
clear();
}, false);

keyRange.addEventListener('click', function(e) {
keyRangeQuery();
}),

indexBtn.addEventListener('click', function(e) {
useIndex();
})

</script>

</body>
</html>

履新三个目的

为了修改多少个指标,首先要把它抽取来,改善,然后再放回去。

var transaction = db.transaction(["students"],"readwrite");
var objectStore = transaction.objectStore("students");
var request = objectStore.get(rollNo);
request.onsuccess = function(event){
    console.log("Updating : "+request.result.name + " to " + name);
    request.result.name = name;
    objectStore.put(request.result);
};

所有的源代码都在这里。如果有任何的问题,请留言,或通过 @歪脖骇客 给我私信

据说事务

区别于一些思想的关周详据库的贯彻,每贰个对数据库操作是在四个业务的光景文中试行的。事务节制一次影响叁个或多少个object stores,你通过传播四个object store名字的数组到创制专业节制的函数来定义。

创设工作的第4个参数是事情方式。当号召一个事务时,必需决定是依照只读照旧读写格局央浼访谈。事务是能源密集型的,所以假若你无需改革data store中的数据,你只供给以只读方式对object stores群集举办号令访谈。

清单2示范了怎么利用非常的情势创设一个事务,并在此片小说的 Implementing Database-Specific Code 部分进行了详尽座谈。

事务和询问操作数据

最轻巧易行的创制事业的不二等秘书诀是:
var transaction = db.transaction(); // db就是前面的数据库对象
这种艺术开创的政工,只好读取数据库中保留的具备目的

貌似用法是:
var transaction = db.transaction('customes', 'readwrite');
意味着只加载customers对象存款和储蓄空间中的数据,并且是以可读可写的形式加载

纵然不传第1个参数,则表示只可访问,不可改善;

此处再次来到的transaction是工作的目录

然后接受objectStore()艺术并传到对象存款和储蓄空间的称谓,就能够访谈特定的积存空间了;

如下:

let transaction = db.transaction('customers', 'readwrite'); 
let store = transaction.objectStore('customers'); 

赢得了地点的store后,大家能够运用如下方法对数码实行操作:

  • add()和put()方法:用于存储数据
    let req = store.add(data);
  • get(key)方法:获取键为key的靶子
    let req = store.get(key);
  • delete(key)方法:删除键为key的指标
    let req = store.delete(key);
  • clear()方法:清空对象存款和储蓄空间中的全数指标
    let req = store.clear();
    选用上述方法会再次回到二个目的,通过对其增加onsuccess和onerror事件,能够检测操作是还是不是中标

注意:通过oncomplete事件目的,访谈不到get()央求重回的此外数据,必得在响应央求的onsuccess事件管理程序中技巧访问到数量

从ObjectStore里删除对象

去除跟新添同样,需求成立专门的学业,然后调用删除接口,通过key删除对象。

db.transaction(["students"],"readwrite").objectStore("students").delete(rollNo);

自家把语句归拢到了同盟,变得更简短,但效果与利益是同风流倜傥的。

有关作者:cucr

永利皇宫463登录 2

今日头条和讯:@hop_ping 个人主页 · 小编的篇章 · 17

永利皇宫463登录 3

存款和储蓄数据

积攒数占领三种艺术:add()方法put()方法

那二种艺术的分别首要反映在:当要增多数据的靶子存款和储蓄空间中曾经存在有相仿键的数目时,使用add()方法加多数据会报错误,而put()方法规会对现成数量开展更改,所以add()方法平常用于领头化数据,而put()方法用于立异数据

代码如下:

// customerData 为要存储的数据
const customerData = [{ ssn: '444-44-4444', name: 'AAA', age: 35, email: '[AAA@company.com](mailto:AAA@company.com)'},{ ssn: '666-66-6666', name: 'CCC', age: 35, email: '[CCC@company.com](mailto:CCC@company.com)'},{ ssn: '777-77-7777', name: 'DDD', age: 32, email: '[DDD@home.org](mailto:DDD@home.org)'},{ ssn: '555-55-5555', name: 'BBB', age: 32, email: '[BBB@home.org](mailto:BBB@home.org)'},
];

// 创建一个事务,该事务将要对名为“customers”的对象存储空间进行 read和write 操作,并返回事务索引
let transaction = db.transaction('customers', 'readwrite'); 

// 取得索引后,使用objectStore()方法并传入存储空间的名称,就可以访问特定的存储空间,这两步是必须的
let store = transaction.objectStore('customers'); 

// 添加数据到数据库中
for (var i in customerData) {
  // 返回的req也是一个对象,可以为其添加onsuccess和onerror事件,来检测数据是否添加成功
  let req = store.put(customerData[i]);   // 往一个存储空间中添加数据

}
// 判断事务整个操作完成
transaction.oncomplete = function(event) {
  console.log(event.target);
  alert('存储数据完成');
};
}

如上就将数据存款和储蓄到数据库dbNames的customers对象存款和储蓄空间中

地点代码中涉嫌了 [事务],这里先记住:举凡涉及到对数据库的读写删除操作,都亟待经过 [事务] 来完成

张开三个IndexedDB数据库

首先,你需求掌握您的浏览器是还是不是援助IndexedDB。请使用新型版的谷歌浏览器或火狐浏览器。低版本的IE是非常的。

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

if(!window.indexedDB)
{
    console.log("你的浏览器不支持IndexedDB");
}

只要你的浏览器支持IndexedDB,大家就足以展开它。你无法直接张开IndexedDB数据库。IndexedDB需求您创设贰个伸手来张开它。

 var request = window.indexedDB.open("testDB", 2);

率先个参数是数据库的称号,第一个参数是数据库的版本号。版本号能够在进级数据库时用来调解数据库结商谈数量。

但你扩充数据库版本号时,会触发onupgradeneeded事件,那时大概会产出成功、战败和拦截事件两种意况。

var db;
request.onerror = function(event){
    console.log("打开DB失败", event);
}
request.onupgradeneeded   = function(event){
    console.log("Upgrading");
    db = event.target.result;
    var objectStore = db.createObjectStore("students", { keyPath : "rollNo" });
};
request.onsuccess  = function(event){
    console.log("成功打开DB");
    db = event.target.result;
}

onupgradeneeded事件在率先次张开页面初步化数据库时会被调用,或在当有版本号变化时。所以,你应有在onupgradeneeded函数里创制你的蕴藏数据。若无版本号变化,何况页面从前被张开过,你会得到八个onsuccess事件。如若有荒诞发生时则触发onerror事件。假如您前边从没小憩连接,则会接触onblocked事件。

在地点的代码片段里,大家创制了一个Object Store,叫做“students”,用“rollNo”做多少键名。

铺设底工

以此事例从贯彻如此三个模块开头,它承担从数据库读取数据,插入新的对象,更新现存对象,删除单个对象和提供在叁个object store删除全体目的的选项。那一个事例达成的代码是通用的数码访谈代码,您可以在任何object store上采取。

那么些模块是经过二个眼看实施函数表明式(IIFE)实现,它利用对象字面量来提供组织。上边包车型大巴代码是模块的摘要,表达了它的主旨结构。

JavaScript

(function (window) { 'use strict'; var db = { /* implementation here */ }; window.app = window.app || {}; window.app.db = db; }(window));

1
2
3
4
5
6
7
8
(function (window) {
    'use strict';
    var db = {
        /* implementation here */
    };
    window.app = window.app || {};
    window.app.db = db;
}(window));

用这么的结构,能够使这几个应用程序的富有逻辑封装在叁个名字为app的单对象上。其它,数据库相关的代码在四个叫作db的app子对象上。

其一模块的代码应用IIFE,通过传递window对象来确认保障模块的符合节制。使用use strict确定保证这一个函数的代码函数是据守(javascript严厉方式卡塔 尔(英语:State of Qatar)严峻编译准则。db对象作为与数据库人机联作的富有函数的机要容器。最后,window对象检查app的实例是还是不是留存,假如存在,模块使用当前实例,尽管子虚乌有,则创建叁个新目的。风姿罗曼蒂克旦app对象成功再次回到或创办,db对象附加到app对象。

本文的其他部分将代码增多到db对象内(在implementation here会讲评),为应用程序提供一定于数据库的逻辑。因而,如你所见本文后边的有个别中定义的函数,用脑筋想父db对象活动,但全数此外功能都以db对象的积极分子。完整的数据库模块列表见项目清单2。

连续数据库

要动用它必需先打开,通过 indexDB.open(name, version)办法张开三个数据库

  • name : 表示数据要开采的数据库的称呼
  • version:为开拓数据库的本子号

IndexedDB里多少以目的的花样积累,每一个对象都有多个key值索引。IndexedDB里的操作都以事务性的。生机勃勃种对象存款和储蓄在三个objectStore里,objectStore就一定于关周全据Curry的表。IndexedDB可以有众多objectStore,objectStore里能够有那个对象。每种对象足以用key值获取。

使用IndexedDB

前些天,你早就有机遇熟知了有些的完全概念,下一步是发端落到实处基于IndexedDB的应用程序。第二个步骤必要统生机勃勃IndexedDB在差别浏览器的兑现。您能够十分轻易地加上各样厂家本性的选取的自己评论,同临时间在window对象上把它们设置为合法对象相像的名目。上面的清单呈现了window.indexedDB,window.IDBTransaction,window.IDBKeyRange的结尾结果是什么都被更新,它们被安装为对应的浏览器的特定完毕。

JavaScript

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;

1
2
3
4
5
6
7
8
9
10
window.indexedDB = window.indexedDB ||
                   window.mozIndexedDB ||
                   window.webkitIndexedDB ||
                   window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction ||
                   window.webkitIDBTransaction ||
                   window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange ||
                   window.webkitIDBKeyRange ||
                   window.msIDBKeyRange;

现今,每种数据库相关的大局对象具有正确的版本,应用程序能够筹算利用IndexedDB开头工作。

行使办法

IndexedDB vs LocalStorage

IndexedDB和LocalStorage都以用来在浏览器里积累数据,但它们采纳不相同的本事,有例外的用途,你要求基于本人的图景万分的挑精拣肥采用哪一种。LocalStorage是用key-value键值情势存储数据,但跟IndexedDB不均等的是,它的数目并非按对象格局储存。它存储的数码都以字符串方式。若是您想让LocalStorage存款和储蓄对象,你须求依靠JSON.stringify()能将对象产生字符串格局,再用JSON.parse()将字符串还原成对象。但如果要存款和储蓄多量的复杂性的数据,那并非风流倜傥种很好的方案。究竟,localstorage正是特地为小数码多少陈设的,它的api是生龙活虎道的。

IndexedDB很相符积累多量数目,它的API是异步调用的。IndexedDB使用索引存款和储蓄数据,各个数据库操作放在专业中履行。IndexedDB以至还扶植轻便的数据类型。IndexedDB比localstorage强大得多,但它的API也针锋相投复杂。

对此简易的数码,你应当继续利用localstorage,但当您期待存款和储蓄大量数据时,IndexedDB会显著的更切合,IndexedDB能提供你越来越复杂的询问数据的措施。

结论

乘机应用程序的须要的增加,你会发今后客商端高效存款和储蓄大批量的多寡的优势。IndexedDB是足以在浏览器中一向运用且扶植异步事务的文档数据库完结。固然浏览器的支撑大概或不能够维持,但在适当的情况下,集成IndexedDB的Web应用程序具备强盛的客商端数据的寻访能力。

在大多数情景下,全数针对IndexedDB编写的代码是自发基于伏乞和异步的。官方正规有同步API,不过这种IndexedDB只适合web worker的光景文中使用。这篇作品公布时,还尚无浏览器达成的联合格式的IndexedDB API。

必然要保管代码在其余函数域外对厂家特定的indexedDB, IDBTransaction, and IDBKeyRange实例进行了标准化且使用了粗暴形式。那允许你制止浏览器错误,当在strict mode下解析脚本时,它不会容许你对那多个对象重新赋值。

你必需保险只传递正整数的本子号给数据库。传递到版本号的小数值会四舍五入。因而,如若您的数据库近日版本1,您准备访问1.2版本,upgrade-needed事件不会接触,因为版本号最终评估是相像的。

当下实践函数表达式(IIFE)不常叫做区别的名字。一时能够看见那样的代码社团办公室法,它叫做self-executing anonymous functions(自实践无名氏函数卡塔尔国或self-invoked anonymous functions(自调用佚名函数卡塔 尔(英语:State of Qatar)。为更为解释那些名称相关的用意和含义,请阅读Ben Alman的小说Immediately Invoked Function Expression (IIFE) 。

Listing 1: Implementing the getAll function

JavaScript

getAll: function (callback) { db.open(function () { var store = db.getObjectStore(), cursor = store.openCursor(), data = []; cursor.onsuccess = function (e) { var result = e.target.result; if (result && result !== null) { data.push(result.value); result.continue(); } else { callback(data); } }; }); },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
getAll: function (callback) {
 
    db.open(function () {
 
        var
            store = db.getObjectStore(),
            cursor = store.openCursor(),
            data = [];
 
        cursor.onsuccess = function (e) {
 
            var result = e.target.result;
 
            if (result &&
                result !== null) {
 
                data.push(result.value);
                result.continue();
 
            } else {
 
                callback(data);
            }
        };
 
    });
},

Listing 2: Full source for database-specific code (index.db.js)

JavaScript

// index.db.js ; window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange; (function(window){ 'use strict'; var db = { version: 1, // important: only use whole numbers! objectStoreName: 'tasks', instance: {}, upgrade: function (e) { var _db = e.target.result, names = _db.objectStoreNames, name = db.objectStoreName; if (!names.contains(name)) { _db.createObjectStore( name, { keyPath: 'id', autoIncrement: true }); } }, errorHandler: function (error) { window.alert('error: ' + error.target.code); debugger; }, open: function (callback) { var request = window.indexedDB.open( db.objectStoreName, db.version); request.onerror = db.errorHandler; request.onupgradeneeded = db.upgrade; request.onsuccess = function (e) { db.instance = request.result; db.instance.onerror = db.errorHandler; callback(); }; }, getObjectStore: function (mode) { var txn, store; mode = mode || 'readonly'; txn = db.instance.transaction( [db.objectStoreName], mode); store = txn.objectStore( db.objectStoreName); return store; }, save: function (data, callback) { db.open(function () { var store, request, mode = 'readwrite'; store = db.getObjectStore(mode), request = data.id ? store.put(data) : store.add(data); request.onsuccess = callback; }); }, getAll: function (callback) { db.open(function () { var store = db.getObjectStore(), cursor = store.openCursor(), data = []; cursor.onsuccess = function (e) { var result = e.target.result; if (result && result !== null) { data.push(result.value); result.continue(); } else { callback(data); } }; }); }, get: function (id, callback) { id = parseInt(id); db.open(function () { var store = db.getObjectStore(), request = store.get(id); request.onsuccess = function (e){ callback(e.target.result); }; }); }, 'delete': function (id, callback) { id = parseInt(id); db.open(function () { var mode = 'readwrite', store, request; store = db.getObjectStore(mode); request = store.delete(id); request.onsuccess = callback; }); }, deleteAll: function (callback) { db.open(function () { var mode, store, request; mode = 'readwrite'; store = db.getObjectStore(mode); request = store.clear(); request.onsuccess = callback; }); } }; window.app = window.app || {}; window.app.db = db; }(window));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// index.db.js
 
;
 
window.indexedDB = window.indexedDB ||
                   window.mozIndexedDB ||
                   window.webkitIndexedDB ||
                   window.msIndexedDB;
 
window.IDBTransaction = window.IDBTransaction ||
                   window.webkitIDBTransaction ||
                   window.msIDBTransaction;
 
window.IDBKeyRange = window.IDBKeyRange ||
                   window.webkitIDBKeyRange ||
                   window.msIDBKeyRange;
 
(function(window){
 
    'use strict';
 
    var db = {
 
        version: 1, // important: only use whole numbers!
 
        objectStoreName: 'tasks',
 
        instance: {},
 
        upgrade: function (e) {
 
            var
                _db = e.target.result,
                names = _db.objectStoreNames,
                name = db.objectStoreName;
 
            if (!names.contains(name)) {
 
                _db.createObjectStore(
                    name,
                    {
                        keyPath: 'id',
                        autoIncrement: true
                    });
            }
        },
 
        errorHandler: function (error) {
            window.alert('error: ' + error.target.code);
            debugger;
        },
 
        open: function (callback) {
 
            var request = window.indexedDB.open(
                db.objectStoreName, db.version);
 
            request.onerror = db.errorHandler;
 
            request.onupgradeneeded = db.upgrade;
 
            request.onsuccess = function (e) {
 
                db.instance = request.result;
 
                db.instance.onerror =
                    db.errorHandler;
 
                callback();
            };
        },
 
        getObjectStore: function (mode) {
 
            var txn, store;
 
            mode = mode || 'readonly';
 
            txn = db.instance.transaction(
                [db.objectStoreName], mode);
 
            store = txn.objectStore(
                db.objectStoreName);
 
            return store;
        },
 
        save: function (data, callback) {
 
            db.open(function () {
 
                var store, request,
                    mode = 'readwrite';
 
                store = db.getObjectStore(mode),
 
                request = data.id ?
                    store.put(data) :
                    store.add(data);
 
                request.onsuccess = callback;
            });
        },
 
        getAll: function (callback) {
 
            db.open(function () {
 
                var
                    store = db.getObjectStore(),
                    cursor = store.openCursor(),
                    data = [];
 
                cursor.onsuccess = function (e) {
 
                    var result = e.target.result;
 
                    if (result &&
                        result !== null) {
 
                        data.push(result.value);
                        result.continue();
 
                    } else {
 
                        callback(data);
                    }
                };
 
            });
        },
 
        get: function (id, callback) {
 
            id = parseInt(id);
 
            db.open(function () {
 
                var
                    store = db.getObjectStore(),
                    request = store.get(id);
 
                request.onsuccess = function (e){
                    callback(e.target.result);
                };
            });
        },
 
        'delete': function (id, callback) {
 
            id = parseInt(id);
 
            db.open(function () {
 
                var
                    mode = 'readwrite',
                    store, request;
 
                store = db.getObjectStore(mode);
 
                request = store.delete(id);
 
                request.onsuccess = callback;
            });
        },
 
        deleteAll: function (callback) {
 
            db.open(function () {
 
                var mode, store, request;
 
                mode = 'readwrite';
                store = db.getObjectStore(mode);
                request = store.clear();
 
                request.onsuccess = callback;
            });
 
        }
    };
 
    window.app = window.app || {};
    window.app.db = db;
 
}(window));

Listing 3: Full source for user interface-specific code (index.ui.js)

JavaScript

// index.ui.js ; (function ($, Modernizr, app) { 'use strict'; $(function(){ if(!Modernizr.indexeddb){ $('#unsupported-message').show(); $('#ui-container').hide(); return; } var $deleteAllBtn = $('#delete-all-btn'), $titleText = $('#title-text'), $notesText = $('#notes-text'), $idHidden = $('#id-hidden'), $clearButton = $('#clear-button'), $saveButton = $('#save-button'), $listContainer = $('#list-container'), $noteTemplate = $('#note-template'), $emptyNote = $('#empty-note'); var addNoTasksMessage = function(){ $listContainer.append( $emptyNote.html()); }; var bindData = function (data) { $listContainer.html(''); if(data.length === 0){ addNoTasksMessage(); return; } data.forEach(function (note) { var m = $noteTemplate.html(); m = m.replace(/{ID}/g, note.id); m = m.replace(/{TITLE}/g, note.title); $listContainer.append(m); }); }; var clearUI = function(){ $titleText.val('').focus(); $notesText.val(''); $idHidden.val(''); }; // select individual item $listContainer.on('click', 'a[data-id]', function (e) { var id, current; e.preventDefault(); current = e.currentTarget; id = $(current).attr('data-id'); app.db.get(id, function (note) { $titleText.val(note.title); $notesText.val(note.text); $idHidden.val(note.id); }); return false; }); // delete item $listContainer.on('click', 'i[data-id]', function (e) { var id, current; e.preventDefault(); current = e.currentTarget; id = $(current).attr('data-id'); app.db.delete(id, function(){ app.db.getAll(bindData); clearUI(); }); return false; }); $clearButton.click(function(e){ e.preventDefault(); clearUI(); return false; }); $saveButton.click(function (e) { var title = $titleText.val(); if (title.length === 0) { return; } var note = { title: title, text: $notesText.val() }; var id = $idHidden.val(); if(id !== ''){ note.id = parseInt(id); } app.db.save(note, function(){ app.db.getAll(bindData); clearUI(); }); }); $deleteAllBtn.click(function (e) { e.preventDefault(); app.db.deleteAll(function () { $listContainer.html(''); addNoTasksMessage(); clearUI(); }); return false; }); app.db.errorHandler = function (e) { window.alert('error: ' + e.target.code); debugger; }; app.db.getAll(bindData); }); }(jQuery, Modernizr, window.app));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// index.ui.js
 
;
 
(function ($, Modernizr, app) {
 
    'use strict';
 
    $(function(){
 
        if(!Modernizr.indexeddb){
            $('#unsupported-message').show();
            $('#ui-container').hide();
            return;
        }
 
        var
          $deleteAllBtn = $('#delete-all-btn'),
          $titleText = $('#title-text'),
          $notesText = $('#notes-text'),
          $idHidden = $('#id-hidden'),
          $clearButton = $('#clear-button'),
          $saveButton = $('#save-button'),
          $listContainer = $('#list-container'),
          $noteTemplate = $('#note-template'),
          $emptyNote = $('#empty-note');
 
        var addNoTasksMessage = function(){
            $listContainer.append(
                $emptyNote.html());
        };
 
        var bindData = function (data) {
 
            $listContainer.html('');
 
            if(data.length === 0){
                addNoTasksMessage();
                return;
            }
 
            data.forEach(function (note) {
              var m = $noteTemplate.html();
              m = m.replace(/{ID}/g, note.id);
              m = m.replace(/{TITLE}/g, note.title);
              $listContainer.append(m);
            });
        };
 
        var clearUI = function(){
            $titleText.val('').focus();
            $notesText.val('');
            $idHidden.val('');
        };
 
        // select individual item
        $listContainer.on('click', 'a[data-id]',
 
            function (e) {
 
                var id, current;
 
                e.preventDefault();
 
                current = e.currentTarget;
                id = $(current).attr('data-id');
 
                app.db.get(id, function (note) {
                    $titleText.val(note.title);
                    $notesText.val(note.text);
                    $idHidden.val(note.id);
                });
 
                return false;
            });
 
        // delete item
        $listContainer.on('click', 'i[data-id]',
 
            function (e) {
 
                var id, current;
 
                e.preventDefault();
 
                current = e.currentTarget;
                id = $(current).attr('data-id');
 
                app.db.delete(id, function(){
                    app.db.getAll(bindData);
                    clearUI();
                });
 
                return false;
        });
 
        $clearButton.click(function(e){
            e.preventDefault();
            clearUI();
            return false;
        });
 
        $saveButton.click(function (e) {
 
            var title = $titleText.val();
 
            if (title.length === 0) {
                return;
            }
 
            var note = {
                title: title,
                text: $notesText.val()
            };
 
            var id = $idHidden.val();
 
            if(id !== ''){
                note.id = parseInt(id);
            }
 
            app.db.save(note, function(){
                app.db.getAll(bindData);
                clearUI();
            });
        });
 
        $deleteAllBtn.click(function (e) {
 
            e.preventDefault();
 
            app.db.deleteAll(function () {
                $listContainer.html('');
                addNoTasksMessage();
                clearUI();
            });
 
            return false;
        });
 
        app.db.errorHandler = function (e) {
            window.alert('error: ' + e.target.code);
            debugger;
        };
 
        app.db.getAll(bindData);
 
    });
 
}(jQuery, Modernizr, window.app));

Listing 3: Full HTML source (index.html)

JavaScript

<!doctype html> <html lang="en-US"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Introduction to IndexedDB</title> <meta name="description" content="Introduction to IndexedDB"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/css/font-awesome.min.css" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/FontAwesome.otf" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.eot" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.svg" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.ttf" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.woff" > <style> h1 { text-align: center; color:#999; } ul li { font-size: 1.35em; margin-top: 1em; margin-bottom: 1em; } ul li.small { font-style: italic; } footer { margin-top: 25px; border-top: 1px solid #eee; padding-top: 25px; } i[data-id] { cursor: pointer; color: #eee; } i[data-id]:hover { color: #c75a6d; } .push-down { margin-top: 25px; } #save-button { margin-left: 10px; } </style> <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr /2.8.2/modernizr.min.js" ></script> </head> <body class="container"> <h1>Tasks</h1> <div id="unsupported-message" class="alert alert-warning" style="display:none;"> <b>Aww snap!</b> Your browser does not support indexedDB. </div> <div id="ui-container" class="row"> <div class="col-sm-3"> <a href="#" id="delete-all-btn" class="btn-xs"> <i class="fa fa-trash-o"></i> Delete All</a> <hr/> <ul id="list-container" class="list-unstyled"></ul> </div> <div class="col-sm-8 push-down"> <input type="hidden" id="id-hidden" /> <input id="title-text" type="text" class="form-control" tabindex="1" placeholder="title" autofocus /><br /> <textarea id="notes-text" class="form-control" tabindex="2" placeholder="text"></textarea> <div class="pull-right push-down"> <a href="#" id="clear-button" tabindex="4">Clear</a> <button id="save-button" tabindex="3" class="btn btn-default btn-primary"> <i class="fa fa-save"></i> Save</button> </div> </div> </div> <footer class="small text-muted text-center">by <a href="" target="_blank">Craig Shoemaker</a> <a href="" target="_blank"> <i class="fa fa-twitter"></i></a> </footer> <script id="note-template" type="text/template"> <li> <i data-id="{ID}" class="fa fa-minus-circle"></i> <a href="#" data-id="{ID}">{TITLE}</a> </li> </script> <script id="empty-note" type="text/template"> <li class="text-muted small">No tasks</li> </script> <script src="//ajax.googleapis.com/ajax/libs /jquery/1.11.1/jquery.min.js"></script> <script src="index.db.js" type="text/javascript"></script> <script src="index.ui.js" type="text/javascript"></script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<!doctype html>
<html lang="en-US">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Introduction to IndexedDB</title>
        <meta name="description"
              content="Introduction to IndexedDB">
        <meta name="viewport"
              content="width=device-width, initial-scale=1">
        <link rel="stylesheet"
              href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/css/font-awesome.min.css" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/FontAwesome.otf" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.eot" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.svg" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.ttf" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.woff" >
        <style>
            h1 {
                text-align: center;
                color:#999;
            }
 
            ul li {
                font-size: 1.35em;
                margin-top: 1em;
                margin-bottom: 1em;
            }
 
            ul li.small {
                font-style: italic;
            }
 
            footer {
                margin-top: 25px;
                border-top: 1px solid #eee;
                padding-top: 25px;
            }
 
            i[data-id] {
                cursor: pointer;
                color: #eee;
            }
 
            i[data-id]:hover {
                color: #c75a6d;
            }
 
            .push-down {
                margin-top: 25px;
            }
 
            #save-button {
                margin-left: 10px;
            }
        </style>
        <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr
/2.8.2/modernizr.min.js" ></script>
    </head>
    <body class="container">
        <h1>Tasks</h1>
        <div id="unsupported-message"
             class="alert alert-warning"
             style="display:none;">
            <b>Aww snap!</b> Your browser does not support indexedDB.
        </div>
        <div id="ui-container" class="row">
            <div class="col-sm-3">
 
                <a href="#" id="delete-all-btn" class="btn-xs">
                    <i class="fa fa-trash-o"></i> Delete All</a>
 
                <hr/>
 
                <ul id="list-container" class="list-unstyled"></ul>
 
            </div>
            <div class="col-sm-8 push-down">
 
                <input type="hidden" id="id-hidden" />
 
                <input
                       id="title-text"
                       type="text"
                       class="form-control"
                       tabindex="1"
                       placeholder="title"
                       autofocus /><br />
 
                <textarea
                          id="notes-text"
                          class="form-control"
                          tabindex="2"
                          placeholder="text"></textarea>
 
                <div class="pull-right push-down">
 
                    <a href="#" id="clear-button" tabindex="4">Clear</a>
 
                    <button id="save-button"
                            tabindex="3"
                            class="btn btn-default btn-primary">
                                <i class="fa fa-save"></i> Save</button>
                </div>
            </div>
        </div>
        <footer class="small text-muted text-center">by
            <a href="http://craigshoemaker.net" target="_blank">Craig Shoemaker</a>
            <a href="http://twitter.com/craigshoemaker" target="_blank">
                <i class="fa fa-twitter"></i></a>
        </footer>
        <script id="note-template" type="text/template">
            <li>
                <i data-id="{ID}" class="fa fa-minus-circle"></i>
                <a href="#" data-id="{ID}">{TITLE}</a>
            </li>
        </script>
        <script id="empty-note" type="text/template">
            <li class="text-muted small">No tasks</li>
        </script>
        <script src="//ajax.googleapis.com/ajax/libs
/jquery/1.11.1/jquery.min.js"></script>
        <script src="index.db.js" type="text/javascript"></script>
        <script src="index.ui.js" type="text/javascript"></script>
    </body>
</html>

赞 1 收藏 评论

经过key抽取对象

get()方法里传播对象的key值,抽出相应的目的。

var request = db.transaction(["students"],"readwrite").objectStore("students").get(rollNo);
request.onsuccess = function(event){
    console.log("Name : "+request.result.name);    
};

IndexedDB是或不是相符本人的应用程序?

几眼前最要紧的主题材料:“IndexedDB是或不是切合自己的应用程序?“像现在同少年老成,答案是自然则然的:“视意况而定。“首先当你准备在客商端保存数据时,你会考虑HTML5地面存款和储蓄。本地存款和储蓄获得广泛浏览器的扶持,有那多少个便于使用的API。轻松有其优势,但其瑕玷是爱莫能助支撑复杂的追寻战术,存款和储蓄大量的数额,并提供业务扶持。

IndexedDB是贰个数据库。所以,当您想为顾客端做出决定,思索你怎样在服务端接纳三个长久化媒质的数据库。你大概会问本身有个别难点来援救调整客户端数据库是不是顺应您的应用程序,包括:

  • 您的客户通过浏览器访谈您的应用程序,(浏览器卡塔 尔(阿拉伯语:قطر‎援助IndexedDB API吗 ?
  • 您必要仓储大批量的数目在客商端?
  • 您须求在贰个大型的多寡集结中高速稳固单个数分部?
  • 您的架构在客商端供给专门的学问帮衬吗?

假定您对内部的其余难点回答了“是的”,很有极大大概,IndexedDB是您的应用程序的三个很好的候选。

往ObjectStore里大幅度增加对象

为了往数据Curry新增扩张少,大家首先供给创建二个事务,并必要具有读写权限。在indexedDB里其他的存取对象的操作都亟待放在专门的学问里实践。

var transaction = db.transaction(["students"],"readwrite");
transaction.oncomplete = function(event) {
    console.log("Success");
};

transaction.onerror = function(event) {
    console.log("Error");
};  
var objectStore = transaction.objectStore("students");

objectStore.add({rollNo: rollNo, name: name});

前端的数据库:IndexedDB入门

2014/12/27 · 未分类 · IndexedDB

本文由 伯乐在线 - cucr 翻译,黄利民 校稿。未经许可,防止转发!
阿尔巴尼亚语出处:www.codemag.com。迎接参预翻译组。

应用程序须要多少。对超越52%Web应用程序来讲,数据在劳务器端组织和拘留,顾客端通过互连网要求获取。随着浏览器变得愈加有才能,由此可筛选在浏览器存款和储蓄和垄断应用程序数据。

本文向你介绍名叫IndexedDB的浏览器端文书档案数据库。使用lndexedDB,你能够通过惯于在劳动器端数据库大约同样的点子创设、读取、更新和删除大批量的记录。请使用本文中可职业的代码版本去体验,完整的源代码可以通过GitHub库找到。

读到本学科的最终时,你将熟习IndexedDB的基本概念以致如何实现二个应用IndexedDB实行总体的CRUD操作的模块化JavaScript应用程序。让我们有一些亲密IndexedDB并初始吧。

什么是IndexedDB

日常的话,有二种分裂门类的数据库:关系型和文书档案型(也称之为NoSQL或对象)。关周全据库如SQL Server,MySQL,Oracle的数据存款和储蓄在表中。文书档案数据库如MongoDB,CouchDB,Redis将数据集作为个人对象存储。IndexedDB是一个文书档案数据库,它在一丝一毫内停放浏览器中的一个沙盒情形中(强制依据(浏览器卡塔尔国同源计谋)。图1展现了IndexedDB的多少,彰显了数据库的构造

永利皇宫463登录 4

图1:开采者工具查看多个object store

不论什么事的IndexedDB API请参见完整文书档案

对象仓库

object store是IndexedDB数据库的底子。假如你选取过关周全据库,经常能够将object store等价于贰个多少库表。Object stores包含二个或多少个目录,在store中遵循生机勃勃对键/值操作,那提供风姿浪漫种高效稳定数据的方法。

当你布署二个object store,你必须要为store选用贰个键。键在store中能够以“in-line”或“out-of-line”的格局存在。in-line键通过在多少对象上援引path来维持它在object store的唯黄金年代性。为了表明那一点,用脑筋想贰个总结电子邮件地址属性Person对象。您能够配备你的store使用in-line键emailAddress,它能有限帮忙store(长久化对象中的数据卡塔 尔(阿拉伯语:قطر‎的唯风流洒脱性。其余,out-of-line键通过单独于数据的值识别唯风姿浪漫性。在这里种景观下,你可以把out-of-line键比作叁个整数值,它(整数值卡塔尔在关全面据库中出任记录的主键。

图1显得了职务数据保存在职分的object store,它接受in-line键。在此个案例中,键对应于对象的ID值。

指鹿为马冒泡

自然,有时候,需要可能不会按预想达成。IndexedDB API通过荒唐冒泡效果来帮衬追踪和保管不当。要是多少个特定的央浼境遇错误,你能够品味在乞请对象上管理错误,或许你能够允许错误通过调用栈冒泡向上传递。那个冒泡脾气,使得你无需为各种须求达成特定错误管理操作,而是能够选拔只在叁个越来越高端别上加多错误管理,它给您一个时机,保持您的错误管理代码简洁。本文中贯彻的例子,是在一个高档别管理错误,以便更加细粒度操作产生的任何错误冒泡到通用的错误管理逻辑。

展开数据库的需要生命周期

IndexedDB使用事件生命周期管理数据库的开发和配置操作。图2示范了贰个开采的伏乞在放任自流的条件下发出upgrade need事件。

永利皇宫463登录 5

图2:IndexedDB张开央求的生命周期

持有与数据库的竞相初叶于三个张开的央浼。试图张开数据库时,您必须传递三个被倡议数据库的版本号的整数值。在展开央求时,浏览器相比较你传入的用于张开央求的版本号与实际数据库的版本号。借使所诉求的版本号高于浏览器中当前的版本号(或然现在还未存在的数据库),upgrade needed事件触发。在uprade need事件之间,你有机会通过抬高或移除stores,键和索引来垄断object stores。

意气风发经所央求的数据库版本号和浏览器的脚下版本号相近,也许进级历程做到,二个展开的数据库将回来给调用者。

另生机勃勃种采纳

浏览器帮忙本地数据库实际不是从IndexedDB才起来落到实处,它是在WebSQL贯彻之后的黄金时代种新办法。相似IndexedDB,WebSQL是一个客商端数据库,但它看作多个关周详据库的达成,使用结构化查询语言(SQL)与数据库通讯。WebSQL的野史充满了波折,但底线是平素不主流的浏览器厂家对WebSQL继续援助。

设若WebSQL实际上是三个丢掉的本事,为啥还要提它呢?有意思的是,WebSQL在浏览器里拿走稳步的支撑。Chrome, Safari, iOS Safari, and Android 浏览器都援助。其余,实际不是那个浏览器的新颖版本才提供支撑,多数那几个新式最佳的浏览器早前的版本也能够支撑。风趣的是,如若你为WebSQL增多扶助来扶植IndexedDB,你忽地意识,大多浏览器厂家和本子成为支持浏览器内置数据库的某种化身。

所以,如果您的应用程序真正供给二个客商端数据库,你想要达到的最高档其余应用恐怕,当IndexedDB不可用时,恐怕你的应用程序恐怕看起来供给选用使用WebSQL来协助客商端数据架构。纵然文书档案数据库和关周到据库管理数占有生硬的反差,但只要你有精确的肤浅,就足以接受本地数据库营造三个应用程序。

选拔概述

在本教程中,您将学习怎样成立一个应用IndexedDB存款和储蓄数据的模块化JavaScript应用程序。为了打探应用程序是怎样行事的,参照他事他说加以考查图4,它描述了职责应用程序处于空白状态。从这里你可认为列表增多新职责。图5突显了录入了多少个任务到系统的镜头。图6来得怎么删除一个职分,图7显示了正在编辑职责时的应用程序。

永利皇宫463登录 6

图4:空白的职务应用程序

永利皇宫463登录 7

图5:任务列表

永利皇宫463登录 8

图6:删除职务

永利皇宫463登录 9

图7:编辑职分
当今您掌握的应用程序的意义,下一步是始于为网址铺设幼功。

本文由永利皇宫463登录发布于首页,转载请注明出处:浏览器里内置的数据库,前端的数据库【永利皇

关键词: