概述

前篇:web API简介(三):客户端储存之Web Storage API

客户端储存从某一方面来说和动态网站差不多。动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据。

IndexedDB API就是现代HTML5客户端储存的方法之二。

IndexedDB介绍

IndexedDB是专门为大量结构化数据设计的。

IndexedDB有这些特性

(1)IndexedDB数据库储存的是键值对。

(2)IndexedDB是基于事务型数据库模型的。

(3)IndexedDB API是异步型的。

(4)IndexedDB使用很多请求(requests)和响应。

(5)IndexedDB使用DOM通知你,当结果被返回的时候。

(6)IndexedDB数据库是对象型的数据库。

(7)IndexedDB不使用SQL。

(8)IndexedDB遵循同源政策。


IndexedDB有这些限制

(1)不支持international sorting。

(2)不支持同步操作。你必须自己写同步操作代码。

(3)不支持全文搜索的部分功能,比如SQL中的LIKE功能。

储存限制

indexedDB的Storage属性有2种:永久型和临时型。

永久型数据没有任何限制,永久储存,只有当用户删除它的时候才会被删除。

临时型数据有一个全局限制和同源限制。全局限制是指临时性数据的总量不能超过磁盘总量的50%。当超出的时候,浏览器会自动删除最久远被用到的数据,直到可以储存目前需要储存的数据。同源限制是指同源下的临时型数据总量有一个限制,这个限制是全局限制的20%,但不低于10M,且不超过2G。当超出同源限制的时候,浏览器会抛出一个错误。

IndexedDB的使用模式

和MongoDB的使用差不多,具体如下:

(1)打开一个数据库。

(2)在数据库中建立一个object store。

(3)开始一项事务,并且用请求来操作数据库。

(4)通过监听DOM事件等待事务完成。

(5)利用返回的数据(request object)做一些操作。

IndexedD的数据库操作

检验是否支持IndexedDB

if (!window.indexedDB) {
window.alert("Your browser doesn't support a stable version of IndexedDB. Such and such feature will not be available.");
}

打开IndexedDB数据库

我们发出一个打开数据库的请求。请求的result是一个IDBDatabase对象。

var request = window.indexedDB.open("MyTestDatabase", 3);

其中3是版本号。版本号不能用小数,否则会被四舍五入成整数。

更新IndexedDB数据库版本

在request发出后,onerror事件和onsuccess事件响应前,如果打开的IndexedDB数据库版本比已经存在的数据库版本低,那么就会出现onerror事件,如果如果打开的IndexedDB数据库版本比已经存在的数据库版本高,就会出现onupgradeneeded事件,在onupgradeneeded事件之后才出现success事件。

var request = indexedDB.open(dbName, 2);

//存在的数据库版本比2低的时候响应如下事件。
request.onupgradeneeded = function(event) { //数据库在event.target的resule属性里面
var db = event.target.result; //建立object store,并设立键值
var objectStore = db.createObjectStore("customers", { keyPath: "ssn" }); //设定object store的索引name,并设定为可以重复
objectStore.createIndex("name", "name", { unique: false }); //设定object store的索引email,并设定为不可以重复
objectStore.createIndex("email", "email", { unique: true });
};

也可以利用autoIncrement设定一个自增长的键值。

//建立object store,并设立自增长的键值,储存在key字段中
var objectStore = db.createObjectStore("customers", { autoIncrement: true });

等待IndexedDB数据库返回

request.onerror = function(event) {
alert("Why didn't you allow my web app to use IndexedDB?!");
};
request.onsuccess = function(event) {
var db;
db = event.target.result;
};

如果更新数据库版本,那么可以在onupgradeneeded事件里面进行增删改查操作,也可以在随后出现的onsuccess事件里面进行。

如果不更新数据库版本,那么不会出现onupgradeneeded事件,这时只能在onsuccess事件里面进行增删改查操作。

IndexedD的增删改查

添加数据

在进行增删改查的时候,我们都需要先给数据库增加一个事务,并且设定事务的状态:readonly,readwrite,和versionchange。

var transaction = db.transaction(["customers"], "readwrite");

transaction方法返回一个IDBTransaction对象,它具有一个方法:objectStore(),这个方法返回一个IDBObjectStore对象。

var objectStore = transaction.objectStore("customers");
customerData.forEach(function(customer) {
var request = objectStore.add(customer);
request.onsuccess = function(event) {
// event.target.result === customer.ssn;
};
});

IDBObjectStore对象的add()方法能够给自己添加数据,并且返回一个请求,这个请求的event.target.result是添加的数据。

注意:add方法只能添加与原有数据不同key的数据,否则就用put方法。

删除数据

删除数据和添加数据类似。

var request = db.transaction(["customers"], "readwrite")
.objectStore("customers")
.delete("444-44-4444");
request.onsuccess = function(event) {
// It's gone!
};

读取数据

db.transaction("customers")
.objectStore("customers")
.get("444-44-4444")
.onsuccess = function(event) {
alert("Name for SSN 444-44-4444 is " + event.target.result.name);
};

注意:transaction默认使用readonly状态。

读取并改写数据

var objectStore = db.transaction(["customers"], "readwrite").objectStore("customers");
var request = objectStore.get("444-44-4444"); request.onsuccess = function(event) {
// Get the old value that we want to update
var data = event.target.result; data.age = 42; var requestUpdate = objectStore.put(data); requestUpdate.onerror = function(event) {
// Do something with the error
};
requestUpdate.onsuccess = function(event) {
// Success - the data is updated!
};
};

IndexedD的游标

基本操作

IDBObjectStore对象的openCursor()方法返回一个请求,这个请求的result就是这个游标本身。这个游标的key是原数据的键值,value是原数据。

var objectStore = db.transaction("customers").objectStore("customers");

objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
alert("Name for SSN " + cursor.key + " is " + cursor.value.name);
cursor.continue();
}
else {
alert("No more entries!");
}
};

利用索引

IDBObjectStore对象的index()方法返回一个打开了index的IDBObjectStore对象(把key设置为index里面的值,把value设置为原数据)。

var index = objectStore.index("name");

index.get("Donna").onsuccess = function(event) {
alert("Donna's SSN is " + event.target.result.ssn);
};

openKeyCursor()方法

IDBObjectStore对象的openCursor()方法返回一个请求,这个请求的result就是这个游标本身。这个游标的key是原数据的键值,value是原数据的主键。

index.openKeyCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
// cursor.key is a name, like "Bill", and cursor.value is the SSN.
// No way to directly get the rest of the stored object.
alert("Name: " + cursor.key + ", SSN: " + cursor.primaryKey);
cursor.continue();
}
};

游标的范围和方向

游标的范围是一个IDBKeyRange对象。

游标的升降序和去重:next,prev,nextunique,prevunique。

如下所示:

// Only match "Donna"
var singleKeyRange = IDBKeyRange.only("Donna"); // Match anything past "Bill", including "Bill"
var lowerBoundKeyRange = IDBKeyRange.lowerBound("Bill"); // Match anything past "Bill", but don't include "Bill"
var lowerBoundOpenKeyRange = IDBKeyRange.lowerBound("Bill", true); // Match anything up to, but not including, "Donna"
var upperBoundOpenKeyRange = IDBKeyRange.upperBound("Donna", true); // Match anything between "Bill" and "Donna", but not including "Donna"
var boundKeyRange = IDBKeyRange.bound("Bill", "Donna", false, true); objectStore.openCursor(boundKeyRange, "prevunique").onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
// Do something with the entries.
cursor.continue();
}
};

锁定数据库

为了防止多人同时改写数据库,可以使用IDBDatabase对象的onblocked属性锁定数据库。

var openReq = mozIndexedDB.open("MyTestDatabase", 2);

openReq.onblocked = function(event) {
// 如果有其它tab试图访问数据库,那么它们必须关闭否则我们不能继续。
alert("Please close all other tabs with this site open!");
}; openReq.onupgradeneeded = function(event) {
// All other databases have been closed. Set everything up.
db.createObjectStore(/* ... */);
useDatabase(db);
}; openReq.onsuccess = function(event) {
var db = event.target.result;
useDatabase(db);
return;
}; function useDatabase(db) { db.onversionchange = function(event) {
db.close();
alert("A new version of this page is ready. Please reload!");
}; // Do stuff with the database.
}

web API简介(四):客户端储存之IndexedDB API的更多相关文章

  1. web API简介(二):客户端储存之document.cookie API

    概述 前篇:web API简介(一):API,Ajax和Fetch 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据.document.cook ...

  2. 如何获取用户的地理位置-浏览器地理位置(Geolocation)API 简介

    如何获取用户的地理位置-浏览器地理位置(Geolocation)API 简介 一.总结 一句话总结:Geolocation API(地理位置应用程序接口)提供了一个可以准确知道浏览器用户当前位置的方法 ...

  3. 开放数据接口 API 简介与使用场景、调用方法

    此文章对开放数据接口 API 进行了功能介绍.使用场景介绍以及调用方法的说明,供用户在使用数据接口时参考之用. 在给大家分享的一系列软件开发视频课程中,以及在我们的社区微信群聊天中,都积极地鼓励大家开 ...

  4. web API简介(三):客户端储存之Web Storage API

    概述 前篇:web API简介(二):客户端储存之document.cookie API 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据. W ...

  5. Web Api 简介

    ASP.NET Web API 简介  ASP.NET MVC 4 包含了 ASP.NET Web API, 这是一个创建可以连接包括浏览器.移动设备等多种客户端的 Http 服务的新框架, ASP. ...

  6. web API简介(一):API,Ajax和Fetch

    概述 今天逛MDN,无意中看到了web API简介,觉得挺有意思的,就认真读了一下. 下面是我在读的时候对感兴趣的东西的总结,供自己开发时参考,相信对其他人也有用. 什么是API API (Appli ...

  7. ASP.NET MVC4中调用WEB API的四个方法

    http://tech.it168.com/a2012/0606/1357/000001357231_all.shtml [IT168技术]当今的软件开发中,设计软件的服务并将其通过网络对外发布,让各 ...

  8. Web API (四) 特性路由(Attribute Route)

    特性路由 是Web API 2 中提出的一种新的类型的路由,正如其名称那样,它是通过特性(Attribute) 来定义路由的,相比之前的基于模式(Convertion Based)的路由,特性路由 能 ...

  9. J2EE基础之Web服务简介

    J2EE基础之Web服务简介 1.什么是Web服务? 在人们的日常生活中,经常会查询网页上某城市的天气信息,这些信息都是动态的.实时的,它是专业的气象站提供的一种服务.例如,在网上购物时,通常采用网上 ...

随机推荐

  1. 卷积神经网络(CNN)张量(图像)的尺寸和参数计算(深度学习)

    分享一些公式计算张量(图像)的尺寸,以及卷积神经网络(CNN)中层参数的计算. 以AlexNet网络为例,以下是该网络的参数结构图. AlexNet网络的层结构如下: 1.Input:       图 ...

  2. Java语法 [HelloWorld]

    程序代码: public class lqx {// AAAAANBBBBCKJKSLJIOQL/*请手打哦!*/ public static void main (String[] args) { ...

  3. javascript隐式原型

    上图是js原型关系图. javascript是一种基于对象的编程语言,但它与一般面向对象的编程语言不同,因为它没有class类的概念 什么是原型?? 我们每创建一个函数,它就会自带一个原型函数,这个原 ...

  4. html css col-md-offset

    有的时候,我们不想让两个相邻的列挨在一起,这时候利用栅格系统的列偏移(offset)功能来实现,而不必再定义margin值.使用.col-md-offset-*形式的样式就可以将列偏移到右侧.例如,. ...

  5. 定义一个包含标签inclusion_tag, 调用模板时报错.. 应该是路径 不对吧...我的templates 是放在app 目录下的.<待处理>

    # 自定义模板标签. 标签的作用,在模板中 实现逻辑,如if ,for 等 from django.template import Library from datetime import datet ...

  6. Yii 框架不同逻辑处理方法统一事务处理

    1.定义事务处理接口 <?php namespace frontend\business\SaveRecordByransactions; /** * Interface ISaveForTra ...

  7. JS数组存储(两个数组相等,一个改变,另一个跟着改变)

    数组是一种引用数据类型,数组引用变量只是一个引用,数组元素和数组变量在内存里是分开存放的实际的数组元素被存储在堆(heap)内存中:数组引用变量是一个引用类型的变量,被存储在栈(stack)内存中. ...

  8. Pains and Sickness 学习笔记

    Headaches can be very painful and can last for a long time. If you have a headache, your head hurts. ...

  9. 20175234 2018-2019-2 《Java程序设计》第四周学习总结

    20175234 2018-2019-2 <Java程序设计>第四周学习总结 教材学习内容总结 教材学习了子类,其重点是方法重写.对象的上转型对象和多态,强调了面向抽象编程的思想. 学习I ...

  10. [原]OpenStreetMap数据瓦片服务性能篇

    上文说到如何利用node-mapnik架设OpenStreetMap瓦片服务,解决了有没有的问题.然而这个服务还是比较孱弱,主要表现在以下几个方面: 1. Node.js只能使用CPU的一个核,不能有 ...