HTML5本地数据库(二)
2015-12-16 15:43
309 查看
indexedDB查询
要做到像在mysql当中那样自由方便的查询数据,需要使用indexedDB的另两个概念,索引和游标索引
索引的好处就是能够迅速定位数据,提高搜索速度,在indexedDB中,有自动增长和keyPath两种索引,上一节我们创建objectStore时使用的键的类型就是keyPath,所以现在我们重点介绍keyPath索引创建索引
索引需要套在创建objectStore的时候使用createIndex方法创建,改方法有三个参数索引名称
索引属性字段名称
索引属性值是否唯一
看下面的代码
<script type="text/javascript"> var mydb; window.onload = function() { var request = window.indexedDB.open("test",1); request.onerror = function(e) { console.log("执行open方法时失败"); }; request.onsuccess = function(e) { mydb = e.target.result; console.log("数据库成功打开或新建"); }; request.onupgradeneeded = function(e) { mydb = e.target.result; if (!mydb.objectStoreNames.contains("student")) { var store = mydb.createObjectStore("student", { keyPath: "id" }); store.createIndex("nameindex", "name", { unique: true }); store.createIndex("ageindex", "age", { unique: false }); }; console.log("版本已经升级"); } } </script>
上面的代码大部分我们已经很熟悉了,我们着重看onupgradeneeded事件中的代码。在使用createObjectStore方法新建objectstore之后,我们使用变量store存储了对新建的student的引用,下面两行代码使用createIndex方法创建了两个索引。第一个索引的名称为”nameindex”,针对的键是”name”,并且标明name键的值是唯一的。第二个索引的名称为”ageindex”,针对的键是”age”,标明age键的值不是唯一的。
这个时候,我们打开开发者工具,查看indexedDB下的新建的test数据库,发现在student下面多了两个索引
新增数据
因为在上一节的最后我们删除了数据库,所以现在再添加一些数据进去function Add() { var student = [{ id: "1002", name: "张三", age: 20, gender: "男", address: "保定" }, { id: "1003", name: "李四", age: 21, gender: "男", address: "国际庄" }, { id: "1004", name: "李丹", age: 22, gender: "女", address: "保定" }]; var transaction = mydb.transaction(["student"], "readwrite"); var obj = transaction.objectStore("student"); for (var i = 0; i < student.length; i++) { obj.add(student[i]); }; }
添加数据之后的结果如图
利用索引获取数据
下面是查询姓名为 李丹 的人的年龄和地址function Query() { var transaction = mydb.transaction(["student"], "readwrite"); var obj = transaction.objectStore("student"); var index = obj.index("nameindex"); index.get("李丹").onsuccess = function(e) { var age = e.target.result.age; var address = e.target.result.address; console.log(age + "," + address); } }
因为我们是根据name查找数据,所以首先使用index方法根据索引名称(nameindex)获取建立在name键的索引,然后使用get方法根据姓名查询数据,这个查询是个请求,如果请求成功的话,则会执行onsuccess事件,在这个事件中,使用e.target.result获取返回的结果,这个结果表示的是整条数据,然后使用.键的方式获取某个键的值
游标
游标的概念我们这里不做解释,你只需要将其想象成一个指针,随着方法的调用这个指针会向下移动,指向下一跳数据使用游标遍历数据
看下面的代码function Cursor() { var transaction = mydb.transaction(["student"], "readwrite"); var obj = transaction.objectStore("student"); var request = obj.openCursor(); request.onsuccess = function(e) { var cursor = e.target.result; if (cursor) { console.log(cursor.key); cursor.continue(); }; } }
上面的代码使用游标输出了所有key的值
openCursor方法用于打开游标,如果这个请求成功的话,会执行onsuccess事件
这个时候游标指向的是student中的第一条数据,e.target.result获取的就是这条数据,包括键的值
然后使用if(cursor)判断这个数据是否为空,只要没有指向最后一条数据的后面,就不会为空
如果不为空,则输出这条数据中的key的值
最后使用continue方法将游标指向下一条数据
所以我们最后看到的输出是这样的
当然如果是想输出所有的name的值,则需要修改一下if (cursor)后面的代码
if (cursor) { var value=cursor.value; console.log(value.name); cursor.continue(); };
输出结果如下
不得不结合
考虑下面的需求,查询出所有年龄为20的人的姓名,使用索引我们可以编写如下代码function QueryAge() { var transaction = mydb.transaction(["student"], "readwrite"); var obj = transaction.objectStore("student"); var index = obj.index("ageindex"); index.get(20).onsuccess = function(e) { var name = e.target.result.name; console.log(name); } }
查询结果如下
我们发现只查询出张三,事实上王聪的年龄也是20,但是只查询出一条
若想查询出全部的年龄是20的数据,则需要索引与游标相结合
function QueryAge() { var transaction = mydb.transaction(["student"], "readwrite"); var obj = transaction.objectStore("student"); var index = obj.index("ageindex"); var request = index.openCursor(IDBKeyRange.only(20)); request.onsuccess = function(e) { var cursor = e.target.result; if (cursor) { var student = cursor.value; console.log(student.name); cursor.continue(); }; } }
简单解释一下:
当前是在ageindex索引上打开游标,而不是student上
cursor.value获取的是除key意外的数据,cursor.key获取的是key的值
下面我们着重解释一下IDBKeyRange.only的意义
KeyRange
上面代码中的index.openCursor方法如果没有参数会获取所有的数据,KeyRange作用是限制游标中的值的范围。它有下面几种类型,分别用于不同的情况IDBKeyRange.only(value):只获取指定值得数据,如上面值获取年龄为20的数据
IDBKeyRange.lowerBound(value,isOpen):获取最小是value的数据,第二个参数用来指示是否排除value值本身,如IDBKeyRange.lowerBound(26,false)的作用是获取所有年龄>=20的数据
IDBKeyRange.upperBound(value,isOpen):和上面类似,用于获取最大值是value的数据,如IDBKeyRange.lowerBound(20,false)的作用是获取所有年龄<=20的数据
IDBKeyRange.bound(value1,value2,isOpen1,isOpen2):用户获取值得范围在value1和value2之间的数据,如如IDBKeyRange.lowerBound(20,22,false,false)的作用是获取所有年龄>=20并<=22的数据
有了上面的几个方法,我们就可以自由的获取需要的数据了
比如下面获取的是年龄>20岁的任的姓名
function QueryAge() { var transaction = mydb.transaction(["student"], "readwrite"); var obj = transaction.objectStore("student"); var index = obj.index("ageindex"); var request = index.openCursor(IDBKeyRange.lowerBound(20,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>
<script type="text/javascript">
var mydb;
window.onload = function() {
var request = window.indexedDB.open("test");
request.onerror = function(e) {
console.log("执行open方法时失败");
};
request.onsuccess = function(e) {
mydb = e.target.result;
console.log("数据库成功打开或新建");
};
request.onupgradeneeded = function(e) {
mydb = e.target.result;
if (!mydb.objectStoreNames.contains("student")) {
var store = mydb.createObjectStore("student", {
keyPath: "id"
});
store.createIndex("nameindex", "name", {
unique: true
});
store.createIndex("ageindex", "age", {
unique: false
});
};
console.log("版本已经升级");
}
}
function Add() {
var student = [{
id: "1001",
name: "张三",
age: 20,
gender: "男",
address: "保定"
}, {
id: "1002",
name: "李四",
age: 21,
gender: "男",
address: "国际庄"
}, {
id: "1003",
name: "李丹",
age: 22,
gender: "女",
address: "保定"
}, {
id: "1004",
name: "王聪",
age: 20,
gender: "女",
address: "保定"
}, {
id: "1005",
name: "萧然",
age: 22,
gender: "女",
address: "保定"
}];
var transaction = mydb.transaction(["student"], "readwrite");
var obj = transaction.objectStore("student");
for (var i = 0; i < student.length; i++) {
obj.add(student[i]);
};
}
function Query() { var transaction = mydb.transaction(["student"], "readwrite"); var obj = transaction.objectStore("student"); var index = obj.index("nameindex"); index.get("李丹").onsuccess = function(e) { var age = e.target.result.age; var address = e.target.result.address; console.log(age + "," + address); } }
function Cursor() {
var transaction = mydb.transaction(["student"], "readwrite");
var obj = transaction.objectStore("student");
var request = obj.openCursor();
request.onsuccess = function(e) {
var cursor = e.target.result;
if (cursor) {
var value = cursor.value;
console.log(value.name);
cursor.continue();
};
}
}
function QueryAge() {
var transaction = mydb.transaction(["student"], "readwrite");
var obj = transaction.objectStore("student");
var index = obj.index("ageindex");
var request = index.openCursor(IDBKeyRange.lowerBound(20,true));
request.onsuccess = function(e) {
var cursor = e.target.result;
if (cursor) {
var student = cursor.value;
console.log(student.name);
cursor.continue();
};
}
}
</script>
</head>
<body>
</body>
<input type="button" name="btnAdd" onclick="Add()" value="添加数据">
<input type="button" name="btnQuery" onclick="Query()" value="查询数据">
<input type="button" name="btnCursor" onclick="Cursor()" value="使用游标遍历数据">
<input type="button" name="btnQueryAge" onclick="QueryAge()" value="根据年龄查询">
</html>
相关文章推荐
- 数据库_韩忠康老师Mysql视频教程
- mongodb数据同步
- Redis 集群方案
- 集群服务器Session同步及一种基于Memcached的session同步
- redis主从切换
- MongoDB数据转移到Mysql库进行数据分析
- MySQL中Distinct和Group By语句的基本使用教程
- SQL Server 2005 sa登录失败。已成功与服务器建立连接 但是在登录过程中发生错误。 provider 共享内存提供程序 error 0 管道的另一端上无任何进程。
- [置顶] MySql错误代码1045的解决方案
- MySQL-数据库总结
- 源码探索系列4---数据库ORM框架之Ormlite解析
- Redis安装及主从配置
- sql 时间转换问题 from_unixtime() UNIX_TIMESTAMP()
- redis集群部署
- MySql4MAC
- SQLSERVER临时表引发的"锁"案
- MySQL中对查询结果排序和限定结果的返回数量的用法教程
- sql重置标识
- oracle 启动em (使用浏览器打开)
- phpredis:php一个key-value用法