html5 app 数据库,HTML5本地数据库(二)

indexedDB查询

要做到像在mysql当中那样自由方便的查询数据,需要使用indexedDB的另两个概念,索引和游标

索引

索引的好处就是能够迅速定位数据,提高搜索速度,在indexedDB中,有自动增长和keyPath两种索引,上一节我们创建objectStore时使用的键的类型就是keyPath,所以现在我们重点介绍keyPath索引

创建索引

索引需要套在创建objectStore的时候使用createIndex方法创建,改方法有三个参数

索引名称

索引属性字段名称

索引属性值是否唯一

看下面的代码

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("版本已经升级");

}

}

上面的代码大部分我们已经很熟悉了,我们着重看onupgradeneeded事件中的代码。在使用createObjectStore方法新建objectstore之后,我们使用变量store存储了对新建的student的引用,下面两行代码使用createIndex方法创建了两个索引。第一个索引的名称为”nameindex”,针对的键是”name”,并且标明name键的值是唯一的。第二个索引的名称为”ageindex”,针对的键是”age”,标明age键的值不是唯一的。

这个时候,我们打开开发者工具,查看indexedDB下的新建的test数据库,发现在student下面多了两个索引

0818b9ca8b590ca3270a3433284dd417.png

新增数据

因为在上一节的最后我们删除了数据库,所以现在再添加一些数据进去

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]);

};

}

添加数据之后的结果如图

0818b9ca8b590ca3270a3433284dd417.png

利用索引获取数据

下面是查询姓名为 李丹 的人的年龄和地址

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获取的就是这条数据,包括键的值

0818b9ca8b590ca3270a3433284dd417.png

然后使用if(cursor)判断这个数据是否为空,只要没有指向最后一条数据的后面,就不会为空

如果不为空,则输出这条数据中的key的值

最后使用continue方法将游标指向下一条数据

所以我们最后看到的输出是这样的

0818b9ca8b590ca3270a3433284dd417.png

当然如果是想输出所有的name的值,则需要修改一下if (cursor)后面的代码

if (cursor) {

var value=cursor.value;

console.log(value.name);

cursor.continue();

};

输出结果如下

0818b9ca8b590ca3270a3433284dd417.png

不得不结合

考虑下面的需求,查询出所有年龄为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);

}

}

查询结果如下

0818b9ca8b590ca3270a3433284dd417.png

我们发现只查询出张三,事实上王聪的年龄也是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();

};

}

}

结果如图

0818b9ca8b590ca3270a3433284dd417.png

完整案例

indexedDB

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();

};

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值