HTML5本地存储IndexedDB基础使用

做项目时需要用H5本地存储,感觉还不错 下面是一些基础知识和一个完整的实例

  

HTML5 的一个重要特性是本地数据持久性,它使用户能够在线和离线访问 Web 应用程序。此外,本地数据持久性使移动应用程序更灵敏,使用的带宽更少,而且能够在低带宽场景中更高效地工作。HTML5 提供了一些本地数据持久性选项。第一个选项是 localstorage,它支持您使用一个简单的键值对来存储数据。IndexedDB(一个更加强大的选项)支持您本地存储大量对象,并使用健壮的数据访问机制检索数据。

IndexedDB API 取代了 Web Storage API,后者在 HTML5 规范中已不推荐使用。(但一些领先的浏览器仍然支持 Web Storage,其中包括苹果公司的 Safari 和 Opera Web 浏览器)与 Web Storage 相比,IndexedDB 具有多个优势,其中包括索引、事务处理和健壮的查询功能。本文将通过一系列的示例来展示如何管理 IndexedDB 数据库。

重要概念

一个网站可能有一个或多个 IndexedDB 数据库,每个数据库必须具有惟一的名称。

一个数据库可包含一个或多个对象存储。一个对象存储(由一个名称惟一标识)是一个记录集合。每个记录有一个 和一个。该值是一个对象,可拥有一个或多个属性。键可能基于某个键生成器,从一个键路径衍生出来,或者是显式设置。一个键生成器自动生成惟一的连续正整数。键路径定义了键值的路径。它可以是单个 JavaScript 标识符或多个由句点分隔的标识符。

规范中包含一个异步 API 和一个同步 API。同步 API 用于 Web 浏览器中。异步 API 使用请求和回调。

在以下示例中,输出附加到一个具有 ID resultdiv 标记上。要更新 result 元素,可在每个数据操作期间清除并设置 innerHTML 属性。每个示例 JavaScript 函数由 HTML 按钮的一个 onclick 事件调用。

object store

有了数据库后我们自然希望创建一个表用来存储数据,但indexedDB中没有表的概念,而是objectStore,一个数据库中可以包含多个objectStore,objectStore是一个灵活的数据结构,可以存放多种类型数据。也就是说一个objectStore相当于一张表,里面存储的每条数据和一个键相关联。

我们可以使用每条记录中的某个指定字段作为键值(keyPath),也可以使用自动生成的递增数字作为键值(keyGenerator),也可以不指定。选择键的类型不同,objectStore可以存储的数据结构也有差异

事务

在对新数据库做任何事情之前,需要开始一个事务。事务中需要指定该事务跨越哪些object store。

事务具有三种模式

  1. 只读:read,不能修改数据库数据,可以并发执行
  2. 读写:readwrite,可以进行读写操作
  3. 版本变更:verionchange
当用户访问你的网站时,如果用户的浏览器支持IndexedDB,则首先触发的是upgradeneeded事件

完整示例

<!doctype html>
<html>
<head>
</head>
    
<body>

<script>
var db;
//检测浏览器是否支持 indexedDBOk
function indexedDBOk() {
    return "indexedDB" in window;
}

document.addEventListener("DOMContentLoaded", function() {

    //判断 indexedDBOk 支持 是/否?
    if(!indexedDBOk) return;
    
 //打开数据库  这个变量其中一个属性是一个已存在的对象存储list,名为objectStoreNames
    var openRequest = indexedDB.open("idarticle_people6",1);

    openRequest.onupgradeneeded = function(e) {

        var thisDB = e.target.result;
    //通过contains方法检车某个对象是否已经存在了,如果不存在则可进行创建
        if(!thisDB.objectStoreNames.contains("people")) {
            
            //使用key生成器
            var os = thisDB.createObjectStore("people", {autoIncrement:true});


            //索引
           //os.createIndex(索引名称,列,指定某个列是否是唯一)
            os.createIndex("name", "name", {unique:false});
            //I want email to be unique
            os.createIndex("email", "email", {unique:true});
        }
    }

    openRequest.onsuccess = function(e) {

        db = e.target.result;

        //监听添加事件
        document.querySelector("#addButton").addEventListener("click", addPerson, false);

        
        document.querySelector("#getButton").addEventListener("click", getPeople, false);

          document.querySelector("#delete").addEventListener("click", deleteData, false);

            document.querySelector("#getStore").addEventListener("click", getDataByKey, false);

         document.querySelector("#getButton1").addEventListener("click", getDataByKey1, false);

         document.querySelector("#getButton2").addEventListener("click", getDataByKey2, false);


    }    

    openRequest.onerror = function(e) {
        //Do something for the error
    }


},false);


function addPerson(e) {
    var name = document.querySelector("#name").value;
    var email = document.querySelector("#email").value;

    console.log("About to add "+name+"/"+email);

    // 对象 = db.事物(将要处理的数组,事物类型)

    var transaction = db.transaction(["people"],"readwrite");
    //设置存储对象people为为读写操作,然后使用objectStore指定要操作的存储对象,存在变量store
    var store = transaction.objectStore("people");

    //设置添加数据
    var person = {
        name:name,
        email:email,
        created:new Date()
    }

    //声明一个普通的javascript对象,使用store的add方法 增加这个对象到对象存储中
    var request = store.add(person);


   //增加数据是异步操作,增加两个事件监听
    request.onerror = function(e) {
        alert("Sorry, that email address already exists.");
        console.log("Error",e.target.error.name);
        console.dir(e.target);
        //some type of error handler
    }

    request.onsuccess = function(e) {
        console.log("Woot! Did it");
    }
}


function getPeople(e) {
    var name = document.querySelector("#nameSearch").value;

    var endname = document.querySelector("#nameSearchEnd").value;

    if(name == "" && endname == "") return;

    // 对象 = db.事物(将要处理的数组,事物类型)
    var transaction = db.transaction(["people"],"readonly");

    //设置存储对象people为为读写操作,然后使用objectStore指定要操作的存储对象,存在变量store
    var store = transaction.objectStore("people");
    
    var index = store.index("name");

    //Make the range depending on what type we are doing
    var range;
    if(name != "" && endname != "") {
        range = IDBKeyRange.bound(name, endname);
    } else if(name == "") {
        range = IDBKeyRange.upperBound(endname);
    } else {
        range = IDBKeyRange.lowerBound(name);
    }

    var s = "";

    index.openCursor(range).onsuccess = function(e) {
        var cursor = e.target.result;
        if(cursor) {
            s += "<h2>Key "+cursor.key+"</h2><p>";
            for(var field in cursor.value) {
                s+= field+"="+cursor.value[field]+"<br/>";
            }
            s+="</p>";
            cursor.continue();
        }
        document.querySelector("#status").innerHTML = s;
    }

}


//清空store
function deleteData(e) {
var transaction = db.transaction(["people"],"readwrite");
 var store=transaction.objectStore("people");     
 store.clear();
}

//列表查询
    function getDataByKey(e) { 
         var s = ""; 
      
        db.transaction(["people"], "readonly").objectStore("people").openCursor().onsuccess = function(e) { 
            var cursor = e.target.result; 
            if(cursor) { 
                s += "<h2>Key "+cursor.key+"</h2><p>"; 
                for(var field in cursor.value) { 
                    s+= field+"="+cursor.value[field]+"<br/>"; 
                } 
                s+="</p>"; 
                cursor.continue(); 
            } 
            document.querySelector("#status2").innerHTML = s; 
        } 
    } 


//查询
function getDataByKey1(){
    var name = document.querySelector("#nameSearch1").value;
    if(name === "" ) return;

    var transaction = db.transaction(["people"],"readonly");
    var store = transaction.objectStore("people");
    var index = store.index("name");
    var request = index.get(name);
    
            request.onsuccess=function(e){ 
                var result = e.target.result;
                console.log(result.email); 

            };
}


//更新
function getDataByKey2(e){
 var name = document.querySelector("#nameSearch2").value;
     if(name === "" ) return;

var transaction = db.transaction(["people"],"readwrite");
            var store=transaction.objectStore("people"); 

            var index = store.index("name");
            var request=index.get(name); 

            request.onsuccess=function(e){ 
               var result = e.target.result;
               result.email=909;
                store.put(result); 
            };
}
</script>

<input type="text"  placeholder="Name"><br/>
<input type="email"  placeholder="Email"><br/>
<button >Add Data</button>

<p/>

Starting with: <input type="text"  placeholder="Name"><br/>
Ending with: <input type="text"  placeholder="Name"><br/>
<button >Get By Name Range</button>

<p/>

<p>
    <button >delete clear</button>
</p>

<p>
    <button >查找数据(列)</button>
</p>
<p >

</p>
<p/>

<input type="text"  placeholder="Name"><br/>
<button >查找数据</button>

<p/>

<p/>

<input type="text"  placeholder="Name"><br/>
<button >更新数据</button>

<p/>
<div ></div>


</body>
</html>