IndexedDB 也是一种数据库的存储机制,但不同于已经不再支持的 Web SQL Database。IndexedDB 不是传统的关系数据库,可归为 NoSQL 数据库。IndexedDB 又类似于 Dom Storage 的 key-value 的存储方式,但功能更强大,且存储空间更大。
IndexedDB 存储数据是 key-value 的形式。Key 是必需,且要唯一;Key 可以自己定义,也可由系统自动生成。Value 也是必需的,但 Value 非常灵活,可以是任何类型的对象。一般 Value 都是通过 Key 来存取的。
IndexedDB 提供了一组 API,可以进行数据存、取以及遍历。这些 API 都是异步的,操作的结果都是在回调中返回。
下面代码演示了 IndexedDB 中 DB 的打开(创建)、存储对象(可理解成有关系数据的”表“)的创建及数据存取、遍历基本功能。
var db;
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
//浏览器是否支持IndexedDB
if (window.indexedDB) {
//打开数据库,如果没有,则创建
var openRequest = window.indexedDB.open("people_db", 1);
//DB版本设置或升级时回调
openRequest.onupgradeneeded = function(e) {
console.log("Upgrading...");
var thisDB = e.target.result;
if(!thisDB.objectStoreNames.contains("people")) {
console.log("Create Object Store: people.");
//创建存储对象,类似于关系数据库的表
thisDB.createObjectStore("people", { autoIncrement:true });
//创建存储对象, 还创建索引
//var objectStore = thisDB.createObjectStore("people",{ autoIncrement:true });
// //first arg is name of index, second is the path (col);
//objectStore.createIndex("name","name", {unique:false});
//objectStore.createIndex("email","email", {unique:true});
}
}
//DB成功打开回调
openRequest.onsuccess = function(e) {
console.log("Success!");
//保存全局的数据库对象,后面会用到
db = e.target.result;
//绑定按钮点击事件
document.querySelector("#addButton").addEventListener("click", addPerson, false);
document.querySelector("#getButton").addEventListener("click", getPerson, false);
document.querySelector("#getAllButton").addEventListener("click", getPeople, false);
document.querySelector("#getByName").addEventListener("click", getPeopleByNameIndex1, false);
}
//DB打开失败回调
openRequest.onerror = function(e) {
console.log("Error");
console.dir(e);
}
}else{
alert('Sorry! Your browser doesn\'t support the IndexedDB.');
}
//添加一条记录
function addPerson(e) {
var name = document.querySelector("#name").value;
var email = document.querySelector("#email").value;
console.log("About to add "+name+"http://www.cnblogs.com/"+email);
var transaction = db.transaction(["people"],"readwrite");
var store = transaction.objectStore("people");
//Define a person
var person = {
name:name,
email:email,
created:new Date()
}
//Perform the add
var request = store.add(person);
//var request = store.put(person, 2);
request.onerror = function(e) {
console.log("Error",e.target.error.name);
//some type of error handler
}
request.onsuccess = function(e) {
console.log("Woot! Did it.");
}
}
//通过KEY查询记录
function getPerson(e) {
var key = document.querySelector("#key").value;
if(key === "" || isNaN(key)) return;
var transaction = db.transaction(["people"],"readonly");
var store = transaction.objectStore("people");
var request = store.get(Number(key));
request.onsuccess = function(e) {
var result = e.target.result;
console.dir(result);
if(result) {
var s = "Key "+key+"";
for(var field in result) {
s+= field+"="+result[field]+"";
}
document.querySelector("#status").innerHTML = s;
} else {
document.querySelector("#status").innerHTML = "No match!";
}
}
}
//获取所有记录
function getPeople(e) {
var s = "";
db.transaction(["people"], "readonly").objectStore("people").openCursor().onsuccess = function(e) {
var cursor = e.target.result;
if(cursor) {
s += "Key "+cursor.key+"";
for(var field in cursor.value) {
s+= field+"="+cursor.value[field]+"";
}
s+="";
cursor.continue();
}
document.querySelector("#status2").innerHTML = s;
}
}
//通过索引查询记录
function getPeopleByNameIndex(e)
{
var name = document.querySelector("#name1").value;
var transaction = db.transaction(["people"],"readonly");
var store = transaction.objectStore("people");
var index = store.index("name");
//name is some value
var request = index.get(name);
request.onsuccess = function(e) {
var result = e.target.result;
if(result) {
var s = "Name "+name+"";
for(var field in result) {
s+= field+"="+result[field]+"";
}
s+="";
} else {
document.querySelector("#status3").innerHTML = "No match!";
}
}
}
//通过索引查询记录
function getPeopleByNameIndex1(e)
{
var s = "";
var name = document.querySelector("#name1").value;
var transaction = db.transaction(["people"],"readonly");
var store = transaction.objectStore("people");
var index = store.index("name");
//name is some value
index.openCursor().onsuccess = function(e) {
var cursor = e.target.result;
if(cursor) {
s += "Key "+cursor.key+"";
for(var field in cursor.value) {
s+= field+"="+cursor.value[field]+"";
}
s+="";
cursor.continue();
}
document.querySelector("#status3").innerHTML = s;
}
}添加数据Add Data根据Key查询数据Get Data获取所有数据Get EveryOne根据索引:Name查询数据 Get ByName
将上面的代码复制到 indexed_db.html 中,用 Google Chrome 浏览器打开,就可以添加、查询数据。在 Chrome 的开发者工具中,能查看创建的 DB 、存储对象(可理解成表)以及表中添加的数据。
IndexedDB 有个非常强大的功能,就是 index(索引)。它可对 Value 对象中任何属性生成索引,然后可以基于索引进行 Value 对象的快速查询。
要生成索引或支持索引查询数据,需求在首次生成存储对象时,调用接口生成属性的索引。可以同时对对象的多个不同属性创建索引。如下面代码就对name 和 email 两个属性都生成了索引。
var objectStore = thisDB.createObjectStore("people",{ autoIncrement:true });
//first arg is name of index, second is the path (col);
objectStore.createIndex("name","name", {unique:false});
objectStore.createIndex("email","email", {unique:true});
生成索引后,就可以基于索引进行数据的查询。
function getPeopleByNameIndex(e)
{
var name = document.querySelector("#name1").value;
var transaction = db.transaction(["people"],"readonly");
var store = transaction.objectStore("people");
var index = store.index("name");
//name is some value
var request = index.get(name);
request.onsuccess = function(e) {
var result = e.target.result;
if(result) {
var s = "";
} else {
document.querySelector("#status3").innerHTML = "";
}
}
}