html5 web SQL database使用小记
最近高端机项目中要用到离线数据库,一开始考虑到用localstorage,毕竟web SQL database已经不再更新了,不过种种考虑,还是采用了web SQL database,毕竟这个查询起来比较方便。
使用起来并不复杂,但是有些地方还是需要注意一下。
1.在苹果的产品中,创建本地数据库时,会有一个系统弹框事件,用户此时都会被打扰。然后该弹框是系统事件。js无法捕捉到用户点了取消或者确定。但是pm的需求总是很高级的。需求需要当用户点击了取消后,第二次刷新页面,不再出现弹框,然后在页面上出现提示语,点击提示语,然后再出现弹框。纠结很久后,终于做好了该逻辑。
函数中引入了框架zepto(和jq类似);
var db = {};
db.createdb = function(arg) {
arg = $.extend({
error: function() {}
},
arg);
try {
if (!window.openDatabase) {
remind("您的浏览器不支持~。");
} else {
db.dbp = openDatabase('baidu', '1.0', 'Baidu', 10 * 1024 * 1024);
db.dbp.transaction(function(tx) {
tx.executeSql('create table if not exists fav(src unique,id,uid,title)');
});
}
} catch(e) {
arg.error();
remind("创建本地数据库失败~~");
}
}
这段是创建本地数据库的脚本,与其他地方不同的是,这里在catch中,引入了回调函数,出现创建数据库的框,我们无法知道用户点击了取消或者确定,但是如果用户点取消,那么创建数据库事件就会失败,那么,该事件会变相有catch事件捕获。这样,回调函数就能起作用了,我们就能知道用户创建数据库失败了。
说明一下,标准中,
db.dbp = openDatabase('baidu', '1.0', 'Baidu', 10 * 1024 * 1024);
这一句是有回调函数的。就是类似于:
db.dbp = openDatabase('baidu', '1.0', 'Baidu', 10 * 1024 * 1024,function(){//这里是回调函数});
就是数据库创建好后,可以执行回调函数,不过支持的并不好。还好。创建数据库的这个过程不是异步进行的。但是数据库的执行sql语句,都是异步的,什么意思呢?举个例子。
比如执行如下的sql语句。
var res = 0;
db.dbp.transaction(function(tx){
tx.executeSql("select * from fav",[],function(tx,result){
//这里是数据库查询成功的执行函数
res=1;
},function(tx,result){
//这里是数据库查询异常的执行函数
});
});
alert(res);
如果运行这么一段,那么,alert出来的res的值为0,因为查询操作是异步的。
那么,怎么样实现这个需求呢,我们先来了解下为什么会弹框,弹框实际是你创建数据库的一瞬间的行为,就是说你如果进入该页面,如果不创建数据库,那么就不会弹框。那么,我们就有了这个设计思路,可以判断cookie中有没有一个值,比如database=0;
如果database=0表示用户取消操作。那么就不弹框,页面再创建数据库之前,可以先判断一下cookie
如果cookie中这个值不存在,则开始执行数据库创建操作,如果这个值存在,则显示,如果前面的catch函数捕捉到了失败,则说明用户取消了创建数据库(当然也有其他可能导致失败,不过可能性就较小了,不过后续也有文字提示创建,问题也不大。)那么这个时候,可以把cookie中德database设置为0,下次一进来就检查cookie,如果database==0,那么就不创建数据库,而是出现提示问题,点击提示文字后,利用交互事件,再来创建数据库。
2.还有一个值得注意的地方,就是就算本地创建了数据库。如果你不open数据库,那么,你是不能对数据库进行操作的,就是说你再操作数据库之前,必须创建一个变量指向数据库。否则会提示数据库不存在。
下面写写操作数据库的各个方法:
1.打开并创建数据库
db.dbp = openDatabase('baidu', '1.0', 'Baidu', 10 * 1024 * 1024);
db.dbp.transaction(function(tx) {
tx.executeSql('create table if not exists fav(src unique,id,uid,title)');
});
openDatabase后的四个参数,第一个个数据库名,第二个是版本号,第三个是数据库的描述,第四个是数据库的大小。
executesql后面的语句就是sql语句了,创建数据库。
其中fav是数据库名称。以后的很多操作都会用到该名称。上例中src是数据库唯一字段,如果你再写入数据时,src的字段名相同,则会写入失败。
2.插入一行数据
db.insert_row=function(arg) {
arg = $.extend({
src:"www.baidu.com",
id:0,
uid:0,
title:"Baidu",
success:function() {},
error:function() {}
}, arg);
db.dbp.transaction(function(tx) {
tx.executeSql('insert into fav (src,id,uid,title) values (?,?,?,?)', [arg.src,arg.id,arg.uid,arg.title], function(tx, result) {
arg.success(result);
}, function(tx, result) {
arg.error(result);
});
});
上面为插入一条数据。所有的sql执行语句都是如上类似的,先执行sql,然后是一些参数,后面是两个回调函数,第一个是执行成功,第二个是异常。这些sql操作都是异步执行的,如果需要查询结果,则要在回调函数success中进行操作。
3.删除一行数据
db.del_row=function(arg) {
arg = $.extend({
src:"",
success:function() {},
error:function() {}
}, arg);
db.dbp.transaction(function(tx) {
tx.executeSql('delete from fav where src="' + arg.src + '"', [], function(tx, result) {
arg.success(result);
}, function(tx, result) {
arg.error(result);
});
});
}
4.按关键字修改数据库字段
db.update_key=function(arg) {
arg = $.extend({
src:"",
key:"",
value:"" ,
success:function() {},
error:function() {}
}, arg);
db.dbp.transaction(function(tx) {
tx.executeSql('update fav set ' + arg.key + ' = ? where src=?;', [arg.value,arg.src], function(tx, result) {
arg.success(result);
}, function(tx, result) {
arg.success(result);
});
});
}
5.获取一行数据
db.get_row=function(arg) {
arg = $.extend({
src:"",
success:function() {},
error:function() {}
}, arg);
db.dbp.transaction(function(tx) {
var res = 0;
tx.executeSql('select * from fav where src="' + arg.src + '"', [], function(tx, result) {
arg.success(result.rows.item(0));
}, function(tx, result) {
arg.error(result);
});
});
}
某行的数据是result.rows.item(0),你也可以输入result.rows试试看它的结构。
6.插入新的字段
db.insert_title=function(arg) {
arg = $.extend({
title:"",
success:function() {},
error:function() {}
}, arg);
db.dbp.transaction(function(tx) {
tx.executeSql('alter table fav add "' + arg.title + '"', [], function(tx, result) {
arg.success(result);
}, function(tx, result) {
arg.error(result);
});
});
}
7.获取所有数据
db.get_all_data=function(arg){
arg=$.extend({
success:function(){},
error:function(){}
},arg);
db.dbp.transaction(function(tx){
tx.executeSql("select * from fav",[],function(tx,result){
arg.success(result);
},function(tx,result){
arg.error(result);
});
})
}
8.获取一列数据
db.get_column=function(arg){
arg=$.extend({
key:"src",
success:function(){},
error:function(){}
},arg);
db.dbp.transaction(function(tx){
tx.executeSql('select"'+arg.key+'"from fav',[],function(tx,result){
arg.success(result);
},function(tx,result){
arg.error(result);
})
});
}
等等等……操作和sql很像,不过没有sql强大,我测试的时候,再chrome 14.0.835.202 下,还不支持几个关键字排序查询。而且也不能按照关键字排序删除。要实现按排序删除这样的功能,必须要变通。我实现一个功能的时候,需要按照排序删除某个内容时。sql语句如下,或许可以给你点提示:
'delete from fav where src in(select src from fav order by xxx desc limit 1)'
最后,上面所有的函数执行的时候,都必须保证数据库已经打开,就是你的db.dbp必须已经申明了,如下
db.dbp = openDatabase('baidu', '1.0', 'Baidu', 10 * 1024 * 1024);
db.dbp.transaction(function(tx) {
tx.executeSql('create table if not exists fav(src unique,id,uid,title)');
});
