Introduction
IndexedDB is an HTML5 WEB database that allows HTML5 WEB applications to store data on the user's browser. IndexedDB is very powerful and useful for applications. It can store a large amount of data in the client's chrome, IE, Firefox and other WEB browsers. Here is a brief introduction to the basic concepts of IndexedDB.
What is IndexedDB
IndexedDB, HTML5’s new data storage, can store and operate data on the client, making applications load faster and respond better. It is different from a relational database in that it has data tables and records. It affects the way we design and create applications. IndexedDB creates objects with data types and simple JavaScript persistent objects. Each object can have an index, making it efficient to query and traverse the entire collection. This article gives you a real-life example of how to use IndexedDB in a web application.
Start
We need to include the following pre-code before execution
JavaScript CodeCopy content to clipboard
-
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB | | window.msIndexedDB;
-
-
//prefixes of window.IDB objects
-
var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
-
var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange
-
-
if (!indexedDB) {
-
alert("Your browser doesn't support a stable version of IndexedDB.")
-
}
Open IndexedDB
Before creating the database, we first need to create data for the database. Assume we have the following user information:
JavaScript CodeCopy content to clipboard
-
var userData = [
-
{ id: "1", name: "Tapas", age: 33, email: "tapas@example.com" },
-
{ id: "2", name: "Bidulata", age: 55, email: "bidu@home.com" }
-
];
Now we need to open our database using the open() method:
JavaScript CodeCopy content to clipboard
-
var db;
-
var request = indexedDB.open("databaseName", 1);
-
-
request.onerror = function(e) {
-
console.log("error: ", e);
-
};
-
-
request.onsuccess = function(e) {
-
db = request.result;
-
console.log("success: " db);
-
};
-
request.onupgradeneeded = function(e) {
-
-
}
如上所示,我们已经打开了名为"databaseName",指定版本号的数据库,open()方法有两个参数:
1.第一个参数是数据库名称,它会检测名称为"databaseName"的数据库是否已经存在,如果存在则打开它,否则创建新的数据库。
2.第二个参数是数据库的版本,用于用户更新数据库结构。
onSuccess处理
发生成功事件时“onSuccess”被触发,如果所有成功的请求都在此处理,我们可以通过赋值给db变量保存请求的结果供以后使用。
onerror的处理程序
发生错误事件时“onerror”被触发,如果打开数据库的过程中失败。
Onupgradeneeded处理程序
如果你想更新数据库(创建,删除或修改数据库),那么你必须实现onupgradeneeded处理程序,使您可以在数据库中做任何更改。 在“onupgradeneeded”处理程序中是可以改变数据库的结构的唯一地方。
创建和添加数据到表:
IndexedDB使用对象存储来存储数据,而不是通过表。 每当一个值存储在对象存储中,它与一个键相关联。 它允许我们创建的任何对象存储索引。 索引允许我们访问存储在对象存储中的值。 下面的代码显示了如何创建对象存储并插入预先准备好的数据:
JavaScript Code复制内容到剪贴板
-
request.onupgradeneeded = function(event) {
-
var objectStore = event.target.result.createObjectStore("users", {keyPath: "id"});
-
for (var i in userData) {
-
objectStore.add(userData[i]);
-
}
-
}
We create an object store using the createObjectStore() method. This method accepts two parameters: - the stored name and the parameter object. Here, we have an object store called "users" and define the keyPath, which is the attribute that makes the object unique. Here, we use "id" as keyPath, this value is unique in the object store, and we have to ensure that the attribute of this "ID" exists in every object in the object store. Once the object store is created, we can start adding data into it using a for loop.
Manually add data to the table:
We can manually add additional data to the database.
JavaScript CodeCopy content to clipboard
-
function Add() {
-
var request = db.transaction(["users"], "readwrite").objectStore( "users")
-
.add({ id: "3", name: "Gautam", age: 30, email: "gautam@store.org" });
-
-
request.onsuccess = function(e) {
-
alert("Gautam has been added to the database.");
-
};
-
-
request.onerror = function(e) {
-
alert("Unable to add the information.");
-
}
-
-
}
Before we did any CRUD operation (read, write, modify) in the database, we had to use transactions. The transaction() method is used to specify the object storage we want to perform transaction processing. The transaction() method accepts 3 parameters (the second and third are optional). The first is the list of object stores we want to process, the second specifies if we want read only/read-write, and the third is the version change.
Reading data from a table
The get() method is used to retrieve data from object storage. We have previously set the object's id as the keyPath, so the get() method will find an object with the same id value. The following code will return an object we named "Bidulata":
JavaScript CodeCopy content to clipboard
-
function Read() {
-
var objectStore = db.transaction(["users"]).objectStore("users");
-
var request = objectStore.get("2");
-
request.onerror = function(event) {
-
alert("Unable to retrieve data from database!");
-
};
-
request.onsuccess = function(event) {
-
if(request.result) {
-
alert("Name: " request.result.name ", Age: " request.result.age ", Email: " request.result.email);
-
} else {
-
alert("Bidulata couldn't be found in your database!");
-
}
-
};
-
}
从表中读取所有数据
下面的方法检索表中的所有数据。 这里我们使用游标来检索对象存储中的所有数据:
JavaScript Code复制内容到剪贴板
-
function ReadAll() {
-
var objectStore = db.transaction("users").objectStore("users");
-
var req = objectStore.openCursor();
-
req.onsuccess = function(event) {
-
db.close();
-
var res = event.target.result;
-
if (res) {
-
alert("Key " res.key " is " res.value.name ", Age: " res.value.age ", Email: " res.value.email);
-
res.continue();
-
}
-
};
-
req.onerror = function (e) {
-
console.log("Error Getting: ", e);
-
};
-
}
该openCursor()用于遍历数据库中的多个记录。 在continue()函数中继续读取下一条记录。
删除表中的记录
下面的方法从对象中删除记录。
JavaScript Code复制内容到剪贴板
-
function Remove() {
-
var request = db.transaction(["users"], "readwrite").objectStore( "users").delete("1");
-
request.onsuccess = function(event) {
-
alert("Tapas's entry has been removed from your database.");
-
};
-
}
We need to pass the object’s keyPath as a parameter to the delete() method.
Final code
The following method deletes a record from the object source:
JavaScript CodeCopy content to clipboard
-
>
-
<head>
-
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-
<title>IndexedDBtitle>
-
<script type="text/javascript">
-
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
-
-
//prefixes of window.IDB objects
-
var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
-
var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange
-
-
if (!indexedDB) {
-
alert("Your browser doesn't support a stable version of IndexedDB.")
-
}
-
var customerData = [
-
{ id: "1", name: "Tapas", age: 33, email: "tapas@example.com" },
-
{ id: "2", name: "Bidulata", age: 55, email: "bidu@home.com" }
-
];
-
var db;
-
var request = indexedDB.open("newDatabase", 1);
-
-
request.onerror = function(e) {
-
console.log("error: ", e);
-
};
-
-
request.onsuccess = function(e) {
-
db = request.result;
-
console.log("success: " db);
-
};
-
-
request.onupgradeneeded = function(event) {
-
-
}
-
request.onupgradeneeded = function(event) {
-
var objectStore = event.target.result.createObjectStore("users", {keyPath: "id"});
-
for (var i in userData) {
-
objectStore.add(userData[i]);
-
}
-
}
-
function Add() {
-
var request = db.transaction(["users"], "readwrite")
-
.objectStore("users")
-
.add({ id: "3", name: "Gautam", age: 30, email: "gautam@store.org" });
-
-
request.onsuccess = function(e) {
-
alert("Gautam has been added to the database.");
-
};
-
-
request.onerror = function(e) {
-
alert("Unable to add the information.");
-
}
-
-
}
-
function Read() {
-
var objectStore = db.transaction("users").objectStore("users");
-
var request = objectStore.get("2");
-
request.onerror = function(event) {
-
alert("Unable to retrieve data from database!");
-
};
-
request.onsuccess = function(event) {
-
if(request.result) {
-
alert("Name: " request.result.name ", Age: " request.result.age ", Email: " request.result.email);
-
} else {
-
alert("Bidulata couldn't be found in your database!");
-
}
-
};
-
}
-
function ReadAll() {
-
var objectStore = db.transaction("users").objectStore("users");
-
var req = objectStore.openCursor();
-
req.onsuccess = function(event) {
-
db.close();
-
var res = event.target.result;
-
if (res) {
-
alert("Key " res.key " is " res.value.name ", Age: " res.value.age ", Email: " res.value.email);
-
res.continue();
-
}
-
};
-
req.onerror = function (e) {
-
console.log("Error Getting: ", e);
-
};
-
}
-
function Remove() {
-
var request = db.transaction(["users"], "readwrite").objectStore("users").delete("1");
-
request.onsuccess = function(event) {
-
alert("Tapas's entry has been removed from your database.");
-
};
-
}
-
script>
-
head>
-
-
<body>
-
<button onclick="Add()">Add recordbutton>
-
<button onclick="Remove()">Delete recordbutton>
-
<button onclick="Read()">Retrieve single recordbutton>
-
<button onclick="ReadAll()">Retrieve all recordsbutton>
-
body>
-
html>
锁
localStorage是不带lock功能的。那么要实现前端的数据共享并且需要lock功能那就需要使用其它本储存方式,比如indexedDB。indededDB使用的是事务处理的机制,那实际上就是lock功能。
做这个测试需要先简单的封装下indexedDB的操作,因为indexedDB的连接比较麻烦,而且两个测试页面都需要用到
JavaScript Code复制内容到剪贴板
-
//db.js
-
//Encapsulate transaction operations
-
IDBDatabase.prototype.doTransaction=function(f){
-
f(this.transaction(["Obj"],"readwrite").objectStore("Obj"));
-
};
-
//Connect to the database and call the main function after success
-
(function(){
-
//Open the database
-
var cn=indexedDB.open("TestDB",1);
-
//Create data object
-
cn.onupgradeneeded=function(e){
-
e.target.result.createObjectStore("Obj");
-
};
-
//Database connection successful
-
cn.onsuccess=function(e){
-
main(e.target.result);
-
};
-
})();
-
Then there are two test pages
-
<script src="db. js">script>
-
<script>
-
//a.html
-
function main(e){
-
(function callee(){
-
//Start a transaction
-
e.doTransaction(function(e){
-
e.put(1,"test"); //Set the value of test to 1
-
e.put(2,"test"); //Set the value of test to 2
-
});
-
setTimeout(callee);
-
})();
-
};
-
script>
-
<script src="db. js">script>
-
<script>
-
//b.html
-
function main(e){
-
(function callee(){
-
//Start a transaction
-
e.doTransaction(function(e){
-
//Get the value of test
-
e.get("test").onsuccess=function(e){
-
console.log(e.target.result);
-
};
-
});
-
setTimeout(callee);
-
})();
-
};
-
script>
Replace localStorage with indexedDB transaction processing. But the result is different
During the test, there may not be immediate output in b.html because indexedDB is busy processing a.html things, and the b.html transaction is waiting in the transaction queue. But no matter what, the output result will not be the value 1. Because the smallest processing unit of indexedDB is a transaction, not an expression like localStorage. In this way, you only need to put the things that need to be processed between lock and unlock into a transaction. In addition, browser support for indexedDB is not as good as localStorage, so browser compatibility must be considered when using it.