在HTML5本地存储——IndexedDB(一:基本使用)中介绍了关于IndexedDB的基本使用方法,很不过瘾,这篇我们来看看indexedDB的杀器——索引。
熟悉数据库的同学都知道索引的一个好处就是可以迅速定位数据,提高搜索速度,在indexedDB中有两种索引,一种是自增长的int值,一种是keyPath:自己指定索引列,我们重点来看看keyPath方式的索引使用.
我们可以在创建object store的时候指明索引,使用object store的createIndex创建索引,方法有三个参数
- function openDB (name,version) {
- var version=version || 1;
- var request=window.indexedDB.open(name,version);
- request.onerror=function(e){
- console.log(e.currentTarget.error.message);
- };
- request.onsuccess=function(e){
- myDB.db=e.target.result;
- };
- request.onupgradeneeded=function(e){
- var db=e.target.result;
- if(!db.objectStoreNames.contains('students')){
- var store=db.createObjectStore('students',{keyPath: 'id'});
- store.createIndex('nameIndex','name',{unique:true});
- store.createIndex('ageIndex','age',{unique:false});
- }
- console.log('DB version changed to '+version);
- };
- }
这样我们在students 上创建了两个索引
- function getDataByIndex(db,storeName){
- var transaction=db.transaction(storeName);
- var store=transaction.objectStore(storeName);
- var index = store.index("nameIndex");
- index.get('Byron').onsuccess=function(e){
- var student=e.target.result;
- console.log(student.id);
- }
- }
这样我们可以利用索引快速获取数据,name的索引是唯一的没问题,但是对于age索引只会取到第一个匹配值,要想得到所有age符合条件的值就需要使用游标了
在indexedDB中使用索引和游标是分不开的,对数据库熟悉的同学很好理解游标是什么东东,有了数据库object store的游标,我们就可以利用游标遍历object store了。
使用object store的openCursor()方法打开游标
- function fetchStoreByCursor(db,storeName){
- var transaction=db.transaction(storeName);
- var store=transaction.objectStore(storeName);
- var request=store.openCursor();
- request.onsuccess=function(e){
- var cursor=e.target.result;
- if(cursor){
- console.log(cursor.key);
- var currentStudent=cursor.value;
- console.log(currentStudent.name);
- cursor.continue();
- }
- };
- }
curson.contine()会使游标下移,知道没有数据返回undefined
要想获取age为26的student,可以结合游标使用索引
- function getMultipleData(db,storeName){
- var transaction=db.transaction(storeName);
- var store=transaction.objectStore(storeName);
- var index = store.index("ageIndex");
- var request=index.openCursor(IDBKeyRange.only(26))
- request.onsuccess=function(e){
- var cursor=e.target.result;
- if(cursor){
- var student=cursor.value;
- console.log(student.id);
- cursor.continue();
- }
- }
- }
这样我们可是使用索引打开一个游标,参数下面会讲到,在成功的句柄内获得游标便利age为26的student,也可以通过index.openKeyCursor()方法只获取每个对象的key值。
- 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):不用解释了吧
获取名字首字母在B-E的student
- function getMultipleData(db,storeName){
- var transaction=db.transaction(storeName);
- var store=transaction.objectStore(storeName);
- var index = store.index("nameIndex");
- var request=index.openCursor(IDBKeyRange.bound('B','F',false,
- true
- ));
- request.onsuccess=function(e){
- var cursor=e.target.result;
- if(cursor){
- var student=cursor.value;
- console.log(student.name);
- cursor.continue();
- }
- }
- }
- <!DOCTYPE HTML>
- <html>
- <head>
- <title>IndexedDB</title>
- </head>
- <body>
- <script type="text/javascript">
- function openDB (name,version) {
- var version=version || 1;
- var request=window.indexedDB.open(name,version);
- request.onerror=function(e){
- console.log(e.currentTarget.error.message);
- };
- request.onsuccess=function(e){
- myDB.db=e.target.result;
- };
- request.onupgradeneeded=function(e){
- var db=e.target.result;
- if(!db.objectStoreNames.contains('students')){
- var store=db.createObjectStore('students',{keyPath: 'id'});
- store.createIndex('nameIndex','name',{unique:true});
- store.createIndex('ageIndex','age',{unique:false});
- }
- console.log('DB version changed to '+version);
- };
- }
- function closeDB(db){
- db.close();
- }
- function deleteDB(name){
- indexedDB.deleteDatabase(name);
- }
- function addData(db,storeName){
- var transaction=db.transaction(storeName,'readwrite');
- var store=transaction.objectStore(storeName);
- for(var i=0;i<students.length;i++){
- store.add(students[i]);
- }
- }
- function getDataByKey(db,storeName,value){
- var transaction=db.transaction(storeName,'readwrite');
- var store=transaction.objectStore(storeName);
- var request=store.get(value);
- request.onsuccess=function(e){
- var student=e.target.result;
- console.log(student.name);
- };
- }
- function updateDataByKey(db,storeName,value){
- var transaction=db.transaction(storeName,'readwrite');
- var store=transaction.objectStore(storeName);
- var request=store.get(value);
- request.onsuccess=function(e){
- var student=e.target.result;
- student.age=35;
- store.put(student);
- };
- }
- function deleteDataByKey(db,storeName,value){
- var transaction=db.transaction(storeName,'readwrite');
- var store=transaction.objectStore(storeName);
- store.delete(value);
- }
- function clearObjectStore(db,storeName){
- var transaction=db.transaction(storeName,'readwrite');
- var store=transaction.objectStore(storeName);
- store.clear();
- }
- function deleteObjectStore(db,storeName){
- var transaction=db.transaction(storeName,'versionchange');
- db.deleteObjectStore(storeName);
- }
- function fetchStoreByCursor(db,storeName){
- var transaction=db.transaction(storeName);
- var store=transaction.objectStore(storeName);
- var request=store.openCursor();
- request.onsuccess=function(e){
- var cursor=e.target.result;
- if(cursor){
- console.log(cursor.key);
- var currentStudent=cursor.value;
- console.log(currentStudent.name);
- cursor.continue();
- }
- };
- }
- function getDataByIndex(db,storeName){
- var transaction=db.transaction(storeName);
- var store=transaction.objectStore(storeName);
- var index = store.index("ageIndex");
- index.get(26).onsuccess=function(e){
- var student=e.target.result;
- console.log(student.id);
- }
- }
- function getMultipleData(db,storeName){
- var transaction=db.transaction(storeName);
- var store=transaction.objectStore(storeName);
- var index = store.index("nameIndex");
- var request=index.openCursor(null,IDBCursor.prev);
- request.onsuccess=function(e){
- var cursor=e.target.result;
- if(cursor){
- var student=cursor.value;
- console.log(student.name);
- cursor.continue();
- }
- }
- }
- var myDB={
- name:'test',
- version:1,
- db:null
- };
- var students=[{
- id:1001,
- name:"Byron",
- age:24
- },{
- id:1002,
- name:"Frank",
- age:30
- },{
- id:1003,
- name:"Aaron",
- age:26
- },{
- id:1004,
- name:"Casper",
- age:26
- }];
- </script>
- </body>
- </html>
有了游标和索引才能真正发挥indexedDB为例,是不是感觉比自定义对象强大方便了很多呢。