html5储存篇(二)

时间:2023-03-09 13:31:26
html5储存篇(二)
indexedDB
相对于html5 中提到 web SQL Database,w3c已经明确声明放弃对其的继续支持,开始支持新的客户端数据库 indexedDB ,indexedDB 是一种noSQL 的数据库,并将利用 objectStore 来代替 传统数据库中 table 的概念。下面将通过代码来具体熟悉下 indexedDB 及其操作。
    1、创建一个数据库。
        //使浏览器都兼容 indexedDB,其实现在大多浏览器均以支持,包括360,QQ,FF,chrome 但是IE7-IE9;并不支持。
         var indexedDB = window.indexedDB || window.webkitIndexDB || window.mozIndexedDB || window.msIndexedDB;
        //创建一个数据库(打开一个数据库)
         var request = indexedDB.open("admin",1);
        //window.indexedDB.open(dbname,version), 我们通过这个方法创建了一个数据库(如果该数据库之前就存在,此操作则为打开一个数据库。)  dbname :数据库的名称; version :数据库的版本号,该版本号在                       初始化数据库是可选的,其默认值为 1;

html5储存篇(二)

    2、相关的事件处理。
        //indexedDB 中的相关操作是异步的,既是基于请求——响应的模式,因此这里会有一些简单的回调函数 onerror 、onsuccess 、 onupgradeneeded,我们将在IDBOpenDBRequest对象(request),上面调用这些方法
        request = indexedDB.open("admin",2);       
        request.onupgradeneeded = function() {
            alert('onupgradeneeded 事件被调用');
        };
         request.onsuccess = function() {
             alert('onsuccess 事件被调用');
         };
         request.onerror = function() {
             alert('onerror 事件被调用');
         };
        //函数的相关简单说明:onerror:当操作失败时(这里是创建数据库失败,或者是打开数据库失败,由于以后的操作中也会用到 onerror、onsuccess 事件,所以这里用"操作" ),onerror 事件将会被触发,             onupgradeneeded:当创建一个数据库,或者是数据库版本更新时,会触发 onupgradeneeded 事件(在上例中,我们更新了 "admin" 数据库的版本号,所以 onupgradeneeded 事件会被触发),当然我们也可以在这里初始化我们的数据库信息, onsuccess : 当操作成功时,会触发onsuccess 事件。      

html5储存篇(二)

3、相关的数据库处理

      提及数据库的相关处理,当然就是简单的增、删、改、查了,不过在此之前,我们必须明确一些简单的概念。
        objectStore : 由于 indexedDB 是noSQL的一种数据库,因此,他并没有传统数据库中 table的概念,但是他包含了 objectStore,可以帮助我们完成操作。对于 objectStore 我所理解的就是“对象商店”,当然就是用来储藏对象的喽,那对象不就是大家熟悉的 “{ }”嘛,而对象里面的当然就是要储存的数据啦。有过SQL数据库编程的童鞋可以将他理解成 table , 并且 objectStore 与 table 有一点是相同的,即一个数据库中可以有多个objectStore 。
        键: 在这里的键值,我将它理解为 SQL数据库中的“主键”吧,但是在 objectStore 中 ,键有 2 种,其对储存对象的要求是不同的;下面对使用情况作简要的说明:
        键类型                                          适用场景
        不使用                                          任意值,但是每添加一条数据的时候需要指定键参数
        Key Path                                     所储存的对象必须是 javascript 对象, 并且这个对象中必须 包含一个与 Key Path 值相同的属性。
        Key Generator                            所储存的对象可以包含任何类型的值,并且这个值会自增长,
        Key Path/Key Generator           所储存的对象必须是 javascript 对象, 通常情况产生一个新键,并且产生的这个新键的值要与 KeyPath 的名字相同。如果对象中有keyPath指定的属性则不生成新的键值,如果没有自动生成递增键值,填充keyPath指定属性
        事务:在indexedDB 中所有的操作都是基于事务来进行的,这里有些不同于SQL数据库的操作。
        添加数据:
        request.onsuccess = function(event) {
              var db = event.target.result;                                  //这里通过 event.target.result 来取得数据库对象(db)。
              var objectStore = db.createObjectStore("books",{keyPath:"id"});                                //------这里创建了一个数据对象,第一个参数为“数据商店”的名称,第二个参数为其键。
              objectStore.createIndex("name","name",{unique:false});                                  //创建索引,便于以后的查找,第一个参数为索引名称(就是以数据对象中的某一个属性为索引),第二个参数为自定义的其值。unique 为约束,代表在数据对象中,其值必须是唯一的。
              objectStore.createIndex("authorTel","authorTel",{unique:true});
              objectStore.transaction.oncomplete = function(event) {
                      var bookStore = db.transaction(["books"],"readwrite").objectStore("books");                        //这里表示在 books “的数据商店” 中,开启一个读写的事务,此外还有:read 只读;versionchange 版本更新
                      bookStore.add({id : 1, name : "Quarry Memrroes", author : "Fred", authorTel : "12345"});
                      bookStore.add({id : 2, name : "Water Buffaloes", author : "Fred", authorTel : "67890"});
                      bookStore.add({id : 3, name : "Bedrock Nights", author : "Barney", authorTel : "345678"});
              };
         };
        html5储存篇(二)
    获取数据:
    基于主键检索:
    request.onsuccess = function(event) {
          var db = event.target.result;
          var bookStore = db.transaction(["books"],"readwrite").objectStore("books");                                           //该操作如上,在 books “数据商店” 上,开启一个事务。
          var fetch = bookStore.get(3);                                      //这里是获取主键(这里就是 id)的那条数据对象,也可以理解成是一条记录吧!
          fetch.onerror = function() {                                 //这里 error 及下面的 success 函数, 和上面讲述的作用相同,不再赘述了。
               alert("failed");
          };
          fetch.onsuccess = function() {
               if(fetch.result) {                                          // fetch.result  中,保存着我们所检索的那条数据对象,
                    alert(fetch.result.name);                        // 取得那个数据对象中的 name 属性值。
               } else {
                   alert("Not found");
               }
          };
     };
    基于索引检索:
    request.onsuccess = function(event) {
          var db = event.target.result;
          var index = db.transaction(["books"],"readwrite").objectStore("books").index('name');    //这里获取到相应的键名;
          var fetch = index.get("Bedrock Nights");    
          fetch.onerror = function() {  
               alert("failed");
          };
          fetch.onsuccess = function() {
               if(fetch.result) {        
                    alert(fetch.result.id);
               } else {
                    alert("Not found");
               }
          };
     };
    这两者的差别并不大,这里就不再赘述了。
    更新数据:
       request.onsuccess = function(event) {
          var db = event.target.result;
          var objectStore = db.transaction(["books"],"readwrite").objectStore("books");                       //该操作如上,在 books “数据商店” 上,开启一个事务。
          var fetch = objectStore.get(1);                               //首先先要获取到那条数据对象
          fetch.onerror = function() {
               alert("Failed");
          };
          fetch.onsuccess = function() {
               var data = fetch.result;
               data.name = "xxxxxxx";                            //更新那条数据对象中指定属性的值
               var requestUpdate = objectStore.put(data);                      //更改成功后,再将它重新加进去。
               requestUpdate.onerror = function() {
                    alert("change Failed");
               };
               requestUpdate.onsuccess = function() {
                    alert("OK");
               };
          }
     };
   html5储存篇(二)
    删除数据:
    request.onsuccess = function(event) {
          var db = event.target.result;
          var objectStore = db.transaction(["books"],"readwrite").objectStore("books");                            //该操作如上,在 books “数据商店” 上,开启一个事务。
          var deleteObj = objectStore.delete(1);                            //删除 id 为 1 的那条数据对象
          deleteObj.onerror = function() {
               alert("failed");
          };
         deleteObj.onsuccess = function() {
              alert("OK");
          };
   };
  html5储存篇(二)
4、游标的使用:
    当我们使用 get( ) 方法进行检索数据时,必须是要知道要查询的那个数据对象的一些信息的(比如上例中的 id、name),但是如果我们无法知道那些信息,但还是需要查询数据时,这时候我们就会用到“游标”,来帮助我们来遍历查询数据。下面是具体的示例:
    简单使用游标查询:
    request.onsuccess = function(event) {
          var db = event.target.result,
          var objectStore = db.transaction(["books"],"readwrite").objectStore("books");                   //该操作如上,在 books “数据商店” 上,开启一个事务。
          objectStore.openCursor().onsuccess = function(event) {                             //通过 openCursor() 方法,开启游标
               var cursor = event.target.result;
                    if(cursor) {
                    alert(cursor.value.name);                                 //这里 cursor.value 对象中,保存着我们的数据对象,有兴趣的话,可以打印出 cursor 具体查看( console.log(cursor) );
                    cursor.continue();                                          //使游标逐步的往下进行
               } else {
                    alert("No more entries");
               }
          };
    };
    结合索引利用游标进行查询:
    request.onsuccess = function(event) {
          var db = event.target.result,
          var index = db.transaction(["books"],"readwrite").objectStore("books").index("name"); 
          index.openCursor().onsuccess = function(event) {   //通过 openCursor() 方法,开启游标
                 var cursor = event.target.result;
                 if(cursor) {
                        alert(cursor.value.id);
                        cursor.continue();      //使游标逐步的往下进行
                 } else {
                        alert("No more entries");
                 }
          };
     };
    这里的结合索引利用游标查询,即是两种方法的一种综合应用,并不具有新的意义,前面都已经讲过了,这里就不在详细说明了。
    指明游标的方向和范围进行查询
        游标范围:网上查了下讲的很好,直接就拿过来了。在这里附上链接吧,http://www.cnblogs.com/dolphinX/p/3416889.html
    index.openCursor()/index.openKeyCursor()方法在不传递参数的时候会获取object store所有记录,像上面例子一样我们可以对搜索进行筛选
    可以使用key range 限制游标中值的范围,把它作为第一个参数传给 openCursor() 或是 openKeyCursor()
    IDBKeyRange.only(value):只获取指定数据
    IDBKeyRange.lowerBound(value,isOpen):获取最小是value的数据,第二个参数用来指示是否排除value值本身,也就是数学中的是否是开区间
    IDBKeyRange.upperBound(value,isOpen):和上面类似,用于获取最大值是value的数据
    IDBKeyRange.bound(value1,value2,isOpen1,isOpen2):不用解释了吧
    在这里PS下,关于JavaScript中字符比较的问题。。。附上链接 http://www.2cto.com/kf/201408/324339.html
    游标方向:游标的方向默认当然是向下走的了。但是您也可以使用 prev 使他向前。 当然还有 nextunique,prevunique,其用于过滤数据对象中重复的数据。
    request.onsuccess = function(event) {
          var db = event.target.result;
          var index = db.transaction(["books"],"readwrite").objectStore("books").index("name");                              //这里必须要使用索引
          var lowerBoundKeyRange = IDBKeyRange.lowerBound("Water Buffaloes",true);
          index.openCursor(lowerBoundKeyRange).onsuccess = function(event) {
                 var cursor = event.target.result;
                 if (cursor) {
                      alert(cursor.value.id);
                       cursor.continue();
                  }
           }
 };
这里要对.openCursor(range, direction ) 函数做简单的说明,第一个参数指定查询的范围,第二个参数指明查询的方向,如果只想指明查询方向,第一个参数可以设置为 null;
当使用完数据库后应该调用 db.close( ),及时的关闭数据库。
5、删除数据库:
    request.onsuccess = function(event) {
          indexedDB.deleteDatabase("admin");                            //调用indexedDB.deleteDatabase(dbname); 用于删除数据库;
    };
PS: indexedDB 是遵守同源策略的,意味着您不能跨域去操作这些信息。
                       http://www.2cto.com/kf/201408/324339.html