Web前端开发学习之路——数据的保存与读取(二)
认识Web SQL
Web SQL Database 是关系型数据库系统,使用SQLite语法访问数据库。对于以SQL为基础的关系型数据库的用户而言,学习Web SQ可以说是相当轻松的,因此我在同期更新了一些关于Mysql的文章以便学习。Web SQL Database几乎支持各大浏览器,不惜担心应用程序无法使用。虽然W3C已宣布将弃用Web SQL,相信短时间内Web SQL仍然是开发WebAPP数据库的主流。
Web SQL基本操作
Web SQL就技术层面来说,仍然可以打开数据库并进行数据的新增、读取、更新与删除等相关操作,与IndexedDB数据库操作程序没有什么不同。
操作IndexedDB数据库有以下几个步骤:
- 创建数据库;
- 创建交易(transaction);
- 执行SQL语法;
- 取得SQL执行结果
创建数据库
创建数据库时,需要定义数据库的名称、版本、描述以及大小,HTML5 Storage的大小会因设备而已,通常来说Android平台的大小不得超过15MB,而IOS平台不得超过10MB,如果开发时遇到问题,可以适当调小数值。
db = openDatabase(dbName,dbVersion,dbDescription,dbSize);
为了检测是否成功创建数据库,可以检查是否为null,例如:
db = openDatabase("MyDatabase","1.0","first DB",2*1024*1024);
if(!db)
alert("链接数据库失败");
上述语法用于打开名为MyDatabase的数据库,数据库版本为1.0,描述内容为first DB,大小是2MB。当数据存在时会打开数据库,不存在则创建。
如果版本号码与现有数据库版本号码不相符,会无法打开数据库,建议写空白字符串代表不限版本或者用changeVersion方法来更改数据库版本,更改数据库版本的语法架构如下:
db.changeVersion(oldVersionNumber,newVersionNumber,callback,
errorCallback,successCallback);
例如:
db.changeVersion("","1",function(tx){
//executeSql
},function(e){
//失败时执行的语句
},function(){
//成功时执行的语句
});
创建交易
创建交易时使用database.transaction()函数,其格式如下所示。
transaction(querysql,errorCallback,successCallback);
Querysql是实际执行的函数,通常会定义为匿名函数,可以在函数中执行SQL语法。举例来说:
db.transaction(fcunction(tx){
//executeSql
},function(e){
//失败时执行的语句
},function(){
//成功时执行的语句
});
执行SQL语法
Transaction中的querysql就可以使用SQL进行数据库的操作,创建数据表、新增/修改/删除/查询数据等,使用的就是executeSQL函数,格式如下:
executeSql(sqlStatement,arguments,callback,errorCallback);
各个参数说明如下:
- sqlStatement :要执行的SQL语法
- arguments:如果上述sqlStatement使用的SQL语法能够动态变化,可以采用变量的方式,以问号(?)来取代变量,在Arguments中按照问号(?)顺序排列成一串组合,例如:
sqlStatemennt = 'update customer set name= ? where id=?';
Arguments = ['brain','123'];
- callback:成功时获取计算结果的语句,请参考下面的内容
- errorCallback:失败时执行的语句
取得SQL执行结果
当SQL查询执行成功后,就可以用循环来取得执行的结果行,如下所示:
for(var i= 0;i<result.rows.length;i++){
item = result.rows.item(i);
#("div").html(item["name"]+"<br>");
}
结果行以result.rows表示,使用result.rows.length就能得知数据共几条,每条数据使用result.rows.item(index)就可以得到,index指的时行的索引位置,从0开始,取得单条数据之后就可以指定字段名称,从而得到所需的数据。
创建数据表
大多数浏览器使用的SQL后台都是SQLite,SQLite时一个轻型嵌入式关系型数据库(embedded SQL database),它值是一个文件,不要特别的设置,没有服务器和配置文件,对移动设备来说时非常好用的数据库,然而它本身并不是标准语言,也没有完全遵守SQL标准,所以有写SQL语法是无法使用的。下面进入SQLite语法的操作,先来看看创建数据表的语法:
create table tabe_name(
column1 datatype PRIMARY KEY,
column2 datatype,
...
);
table_name是数据表的名称,column是字段的名称,datatype是数据类型,PRIMARY KEY是主键,表示字段中的数据必须是唯一值,不能重复,AUTOINCREMENT是自动编号,举例如下:
CREATE TABLE customer(
id int PRIMARY KEY,
name char(10),
address varchar(200)
);
上述语句创建了3个字段,分别是id、name和address,其中id字段是主键,不允许重复值,name字段的数据类型是10位的char(固定长度的字符串),address是200位的varchar(可变长度的字符串)。
SQLite并不强制指定数据类型,数据保存时会以最合适的保存类别(Storage Class)进行保存,也就试说就算不写数据类型也可以,如下:
CREATE TABLE customer (id,name,address);
SQLite的保存类别只有5种,但几乎包含了所有的数据类型,如下:
- text:当声明为char、varchar、nvarchar、text、clob等字符串类型就被会归类为text,如char(10)、vachar(255)
- numeric:当声明为numeric、decimal(10,50)、boolean、date、datetime时会被归类为numeric
- integer:当声明为int、integer、tinyint、smallint、mediumint等整数类型时会被归类为integer
- real:当声明为real、double、float等浮点数(具有小数点的数值)类型时就会被归类为real
- none:不做任何数据类型操作
当数据表已经存在时,执行create table命令就会出错。我们加上if not exists命令来确保create table命令正常运行,如下:
create table if not exists customer(
id integer primary key,
name char(10),
address varchar(200)
)
下面请看一个范例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SQLite</title>
<script src="../jquery-3.3.1.min.js"></script>
</head>
<script type="text/javascript">
$(function () {
//打开数据库
var dbSize = 2*1024*1024;
db = openDatabase('firstDB','','',dbSize);
//创建数据表
db.transaction(function (tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS customer(id integer PRIMARY KEY,name char(10),address varchar(200))",[],onSuccess,onError);
});
function onSuccess(tx,results) {
$("div").html("打开数据库成功!")
}
function onError(e) {
$("div").html("打开数据错误:"+e.message)
}
})
</script>
<body>
<div id="message"></div>
</body>
</html>
执行后会发现Web SQL新增了customer数据表:
新增、修改和删除数据
新增数据的语法如下:
INSERT INTO tableName(column1,column2,...) VALUES (value1,value2,...)
例如:
INSERT INTO customer(name,address)VALUES('brian','上海市');
SQL语法中的字符串前后只能使用单引号。
如果字段被设置为PRIMARY KEY,当INSERT时没有命令字段值,会直接从字段的最大值加1,相当于设置了AUTOINCREMENT自动编号。
修改数据
修改数据使用的时UPDATE命令,语法如下:
UPDATE tableName SET column1 = value1,colum2 = value2,...WHERE condition;
condition是指要更新的条件,例如,要将id为1的姓名修改成为Jennifer,就可以使用下式表示:
UPDATE customer SET name ='Jennifer' WHERE id =1;
如果要将资料表的某个字段一次更新,只要省略WHERE子句即可,例如要将地址全部改为上海市,就可以使用下式表示:
UPDATE customer SET address ='上海市';
删除数据
删除数据使用的是DELETE命令语法如下:
DELETE FROM tableName WHERE condition;
SQL语法相当容易理解和记忆,DELETE语法就是从某数据表(FROM)中找出符合的数据(WHERE)并删除(DELETE)。举例来说,从customer数据表中删除name为Jennifer的数据,语法如下:
DELETE FROM customer WHERE name ='Jennifer';
WHERE子句指定要删除哪一条数据,如果省略WHERE子句,所有数据都会被删除。
读取数据
要取出数据使用的是SELECT命令,语法如下:
SELECT column1,column2 FROM tableName WHERE condition;
例如:
SELECT id,address FROM customer WHERE name='Jennifer';
找到数据之后可以使用循环来获取,结果以result.rows表示,用result.rows.length就能得知数据共有几条,每条数据使用result.rows.item(index)就可以获取,index指的行的索引位置,从0开始,取得单行数据之后再指定字段名称,就可以取得所需的数据了,如下所示:
for(var i=o;i<result.rows.length;i++){
item = result.rows.item(i);
$("div").html(item["name"]+"<br>");
}
现在就来看看完整的数据库创建和数据新增、删除的范例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SQLite</title>
<script src="../jquery-3.3.1.min.js"></script>
<style>
table{
border-collapse: collapse;
}
td{
border:1px solid #0000cc;
padding: 5px;
}
#message{
color:#ff0000
}
</style>
<script type="text/javascript">
$(function () {
//打开数据库
var dbSize = 2*1024*1024;
db = openDatabase('firstDB','','',dbSize);
db.transaction(function (tx) {
//创建数据表
tx.executeSql("CREATE TABLE IF NOT EXISTS customer(id integer PRIMARY KEY ,name char(10),address varchar(200))");
showAll();
});
$("button").click(function () {
var name =$("#name").val();
var address =$("#address").val();
if(name==""||address==""){
$("#message").html("**请输入姓名和地址**");
return false;
}
db.transaction(function (tx) {
//新增数据
tx.executeSql("INSERT INTO customer(name,address)VALUES (?,?)",[name,address],function (tx,result) {
$("#message").html("新增数据完成!")
showAll();
},function (e) {
$("#message").html("新增数据错误:"+e.message)
});
});
})
$(document).on('click',".delItem",function () {
var delid = $(this).prop("id");
db.transaction(function (tx) {
//删除数据
var delstr ="DELETE FROM customer WHERE id =?";
alert(delstr)
tx.executeSql(delstr,[delid],function (tx,result) {
$("#message").html("删除数据完成!")
showAll();
},function (e) {
$("#message").html("删除数据错误:"+e.errorCode);
});
});
})
function showAll() {
$("#showData").html("");
db.transaction(function (tx) {
//显示customer数据表全部数据
tx.executeSql("SELECT id,name,address FROM customer",[],function (tx,result) {
if(result.rows.length>0){
var str ="现有数据:<br><table><tr><td>id</td><td>姓名</id><td>地址</id><td> </id></tr>;"
for(var i =0;i<result.rows.length;i++){
item = result.rows.item(i);
str +="<tr><td>"+item["id"] + "</td><td>" +item["name"] + "</td><td>" + item["address"] + "</td><td><input type='button' id='"+item["id"]+"'class='delItem' value='删除'></td></tr>";
}
str+="</table>";
$("#showData").html(str);
}
});
},function (e) {
$("#message").html("SELECT语法出错了!"+e.message)
});
}
})
</script>
</head>
<body>
<!--新增-->
<table>
<tr>
<td>姓名:</td>
<td><input type="text" id="name"></td>
</tr>
<tr>
<td>地址:</td>
<td><input type="text" id="address"></td>
</tr>
</table>
<button id = 'new'>发送</button>
<p>
<div id="message"></div>
<div id="showData"></div>
</p>
</body>
</html>
上述代码又是敲代码几分钟,找bug一小时,由于原书中就已经出现bug,在我的仔细观察下还是给它找出来了!执行结果如下:
用户输入数据单击“发送”按钮就可以新增一条记录,单击“删除”按钮来删除记录。然而“删除”按钮是动态产生的,网页加载时并不存在,就不能采用直接绑定,范例中的“发送”、“删除”按钮绑定事件使用的是jQuery语法。