• 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;

           

        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 事件。      

           

        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"});
                  };
             };
     
           
      
        获取数据:
        
        基于主键检索:
        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");
                   };
              }
         };
         
      
     
        删除数据:
        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");
              };
       };
     
     
     
    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 
       
  • 相关阅读:
    洛谷 P5110 块速递推
    洛谷 P3868 [TJOI2009]猜数字
    Codeforces 343D Water Tree
    Codeforces 915E Physical Education Lessons
    洛谷 P2787 语文1(chin1)- 理理思维
    洛谷 P4344 [SHOI2015]脑洞治疗仪
    洛谷 P3338 [ZJOI2014]力
    【模板】珂朵莉树(ODT)(Codeforces 896C Willem, Chtholly and Seniorious)
    【模板】FFT
    Solution of CF911G Mass Change Queries
  • 原文地址:https://www.cnblogs.com/cabbagen/p/4520579.html
Copyright © 2020-2023  润新知