HTML5本地存储——IndexedDB(二:索引)

十度 HTML5 2016年04月29日 收藏

在HTML5本地存储——IndexedDB(一:基本使用)中介绍了关于IndexedDB的基本使用方法,很不过瘾,这篇我们来看看indexedDB的杀器——索引。

熟悉数据库的同学都知道索引的一个好处就是可以迅速定位数据,提高搜索速度,在indexedDB中有两种索引,一种是自增长的int值,一种是keyPath:自己指定索引列,我们重点来看看keyPath方式的索引使用.

创建索引

我们可以在创建object store的时候指明索引,使用object store的createIndex创建索引,方法有三个参数

  • 索引名称
  • 索引属性字段名
  • 索引属性值是否唯一
  1. function openDB (name,version) {
  2.             var version=version || 1;
  3.             var request=window.indexedDB.open(name,version);
  4.             request.onerror=function(e){
  5.                 console.log(e.currentTarget.error.message);
  6.             };
  7.             request.onsuccess=function(e){
  8.                 myDB.db=e.target.result;
  9.             };
  10.             request.onupgradeneeded=function(e){
  11.                 var db=e.target.result;
  12.                 if(!db.objectStoreNames.contains('students')){
  13.                     var store=db.createObjectStore('students',{keyPath: 'id'});
  14.                     store.createIndex('nameIndex','name',{unique:true}); 
  15.                     store.createIndex('ageIndex','age',{unique:false}); 
  16.                 }
  17.                 console.log('DB version changed to '+version);
  18.             };
  19.         }

这样我们在students 上创建了两个索引

image

 

image

利用索引获取数据

  1. function getDataByIndex(db,storeName){
  2.             var transaction=db.transaction(storeName);
  3.             var store=transaction.objectStore(storeName);
  4.             var index = store.index("nameIndex");
  5.             index.get('Byron').onsuccess=function(e){
  6.                 var student=e.target.result;
  7.                 console.log(student.id);
  8.             }
  9.         }

这样我们可以利用索引快速获取数据,name的索引是唯一的没问题,但是对于age索引只会取到第一个匹配值,要想得到所有age符合条件的值就需要使用游标了

游标

在indexedDB中使用索引和游标是分不开的,对数据库熟悉的同学很好理解游标是什么东东,有了数据库object store的游标,我们就可以利用游标遍历object store了。

使用object store的openCursor()方法打开游标

  1. function fetchStoreByCursor(db,storeName){
  2.             var transaction=db.transaction(storeName);
  3.             var store=transaction.objectStore(storeName);
  4.             var request=store.openCursor();
  5.             request.onsuccess=function(e){
  6.                 var cursor=e.target.result;
  7.                 if(cursor){
  8.                     console.log(cursor.key);
  9.                     var currentStudent=cursor.value;
  10.                     console.log(currentStudent.name);
  11.                     cursor.continue();
  12.                 }
  13.             };
  14.         }

curson.contine()会使游标下移,知道没有数据返回undefined

index与游标结合

 

要想获取age为26的student,可以结合游标使用索引

  1. function getMultipleData(db,storeName){
  2.             var transaction=db.transaction(storeName);
  3.             var store=transaction.objectStore(storeName);
  4.             var index = store.index("ageIndex");
  5.             var request=index.openCursor(IDBKeyRange.only(26))
  6.             request.onsuccess=function(e){
  7.                 var cursor=e.target.result;
  8.                 if(cursor){
  9.                     var student=cursor.value;
  10.                     console.log(student.id);
  11.                     cursor.continue();
  12.                 }
  13.             }
  14.         }

这样我们可是使用索引打开一个游标,参数下面会讲到,在成功的句柄内获得游标便利age为26的student,也可以通过index.openKeyCursor()方法只获取每个对象的key值。

指定游标范围

  1. index.openCursor()/index.openKeyCursor()方法在不传递参数的时候会获取object store所有记录,像上面例子一样我们可以对搜索进行筛选
  1. 可以使用key range 限制游标中值的范围,把它作为第一个参数传给 openCursor() 或是 openKeyCursor()
  1. IDBKeyRange.only(value):只获取指定数据
  1. IDBKeyRange.lowerBound(value,isOpen):获取最小是value的数据,第二个参数用来指示是否排除value值本身,也就是数学中的是否是开区间
  1. IDBKeyRange.upperBound(value,isOpen):和上面类似,用于获取最大值是value的数据
  1. IDBKeyRange.bound(value1,value2,isOpen1,isOpen2):不用解释了吧

 

获取名字首字母在B-E的student

  1. function getMultipleData(db,storeName){
  2.             var transaction=db.transaction(storeName);
  3.             var store=transaction.objectStore(storeName);
  4.             var index = store.index("nameIndex");
  5.             var request=index.openCursor(IDBKeyRange.bound('B','F',false,
  6. true
  7. ));
  8.             request.onsuccess=function(e){
  9.                 var cursor=e.target.result;
  10.                 if(cursor){
  11.                     var student=cursor.value;
  12.                     console.log(student.name);
  13.                     cursor.continue();
  14.                 }
  15.             }
  16.         }


 完整示例

 

  1.  <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4.     <title>IndexedDB</title>
  5. </head>
  6. <body>
  7.     <script type="text/javascript">
  8.         function openDB (name,version) {
  9.             var version=version || 1;
  10.             var request=window.indexedDB.open(name,version);
  11.             request.onerror=function(e){
  12.                 console.log(e.currentTarget.error.message);
  13.             };
  14.             request.onsuccess=function(e){
  15.                 myDB.db=e.target.result;
  16.             };
  17.             request.onupgradeneeded=function(e){
  18.                 var db=e.target.result;
  19.                 if(!db.objectStoreNames.contains('students')){
  20.                     var store=db.createObjectStore('students',{keyPath: 'id'});
  21.                     store.createIndex('nameIndex','name',{unique:true}); 
  22.                     store.createIndex('ageIndex','age',{unique:false}); 
  23.                 }
  24.                 console.log('DB version changed to '+version);
  25.             };
  26.         }
  27.  
  28.         function closeDB(db){
  29.             db.close();
  30.         }
  31.  
  32.         function deleteDB(name){
  33.             indexedDB.deleteDatabase(name);
  34.         }
  35.  
  36.         function addData(db,storeName){
  37.             var transaction=db.transaction(storeName,'readwrite'); 
  38.             var store=transaction.objectStore(storeName); 
  39.  
  40.             for(var i=0;i<students.length;i++){
  41.                 store.add(students[i]);
  42.             }
  43.         }
  44.  
  45.         function getDataByKey(db,storeName,value){
  46.             var transaction=db.transaction(storeName,'readwrite'); 
  47.             var store=transaction.objectStore(storeName); 
  48.             var request=store.get(value); 
  49.             request.onsuccess=function(e){ 
  50.                 var student=e.target.result; 
  51.                 console.log(student.name); 
  52.             };
  53.         }
  54.  
  55.         function updateDataByKey(db,storeName,value){
  56.             var transaction=db.transaction(storeName,'readwrite'); 
  57.             var store=transaction.objectStore(storeName); 
  58.             var request=store.get(value); 
  59.             request.onsuccess=function(e){ 
  60.                 var student=e.target.result; 
  61.                 student.age=35;
  62.                 store.put(student); 
  63.             };
  64.         }
  65.  
  66.         function deleteDataByKey(db,storeName,value){
  67.             var transaction=db.transaction(storeName,'readwrite'); 
  68.             var store=transaction.objectStore(storeName); 
  69.             store.delete(value); 
  70.         }
  71.  
  72.         function clearObjectStore(db,storeName){
  73.             var transaction=db.transaction(storeName,'readwrite'); 
  74.             var store=transaction.objectStore(storeName); 
  75.             store.clear();
  76.         }
  77.  
  78.         function deleteObjectStore(db,storeName){
  79.             var transaction=db.transaction(storeName,'versionchange'); 
  80.             db.deleteObjectStore(storeName);
  81.         }
  82.  
  83.         function fetchStoreByCursor(db,storeName){
  84.             var transaction=db.transaction(storeName);
  85.             var store=transaction.objectStore(storeName);
  86.             var request=store.openCursor();
  87.             request.onsuccess=function(e){
  88.                 var cursor=e.target.result;
  89.                 if(cursor){
  90.                     console.log(cursor.key);
  91.                     var currentStudent=cursor.value;
  92.                     console.log(currentStudent.name);
  93.                     cursor.continue();
  94.                 }
  95.             };
  96.         }
  97.  
  98.         function getDataByIndex(db,storeName){
  99.             var transaction=db.transaction(storeName);
  100.             var store=transaction.objectStore(storeName);
  101.             var index = store.index("ageIndex");
  102.             index.get(26).onsuccess=function(e){
  103.                 var student=e.target.result;
  104.                 console.log(student.id);
  105.             }
  106.         }
  107.  
  108.         function getMultipleData(db,storeName){
  109.             var transaction=db.transaction(storeName);
  110.             var store=transaction.objectStore(storeName);
  111.             var index = store.index("nameIndex");
  112.             var request=index.openCursor(null,IDBCursor.prev);
  113.             request.onsuccess=function(e){
  114.                 var cursor=e.target.result;
  115.                 if(cursor){
  116.                     var student=cursor.value;
  117.                     console.log(student.name);
  118.                     cursor.continue();
  119.                 }
  120.             }
  121.         }
  122.  
  123.         var myDB={
  124.             name:'test',
  125.             version:1,
  126.             db:null
  127.         };
  128.  
  129.         var students=[{ 
  130.             id:1001, 
  131.             name:"Byron", 
  132.             age:24 
  133.         },{ 
  134.             id:1002, 
  135.             name:"Frank", 
  136.             age:30 
  137.         },{ 
  138.             id:1003, 
  139.             name:"Aaron", 
  140.             age:26 
  141.         },{ 
  142.             id:1004, 
  143.             name:"Casper", 
  144.             age:26 
  145.         }]; 
  146.     </script>
  147. </body>
  148. </html>
View Code

最后

有了游标和索引才能真正发挥indexedDB为例,是不是感觉比自定义对象强大方便了很多呢。