客户端数据库API为提供了一种简单的方式来存储、检索和处理用户所提供的信息。此外,它还提供了关系数据库模型,因此可以轻松处理复杂的数据。可以使用标准的SQL语句来执行所有与数据库相关的任务,比如创建数据库和表,以及在表中插入、获取、删除和更新行。
首先,来创建并打开一个数据库。以下是创建并打开客户端数据库的代码示例:
var datab;
var shortName = 'tmpCart';
var version = '1.0';
var displayName = 'tmpCart';
var maxSize = 200000;
datab = openDatabase(shortName, version, displayName, maxSize);
在上述代码片段中使用的变量使用情况如表1所示。
变量 | 用途 |
---|---|
datab | 用于在建立数据库连接时持有数据库连接的引用。 |
shortName | 存储将在客户端创建的数据库的名称。 |
version | 存储分配给数据库的版本号。版本号通常用于数据库的升级或更改。 |
displayName | 存储用户可见的数据库名称。 |
maxSize | 存储数据库预期的大小(以千字节为单位)。如果大小超出此变量中的限制,将被通知并询问是否允许增加大小。 |
代码片段中定义的变量值表明想要创建一个名为tmpCart
的客户端数据库,版本号为1.0,大小限制为200000 KB。在分配这些变量值之后,可以将它们传递给openDatabase
命令,该命令实际上创建了tmpCart
数据库,并将连接存储在datab
变量中。
代码片段也可以写成如下形式:
datab = openDatabase('tmpCart', '1.0', 'tmpCart', 200000);
也就是说,可以直接在openDatabase
函数中指定参数值,而不需要使用变量。
现在已经创建并打开了服务器端数据库,让在其中创建一个表。
在这个例子中,将使用客户端数据库来存储购物车信息。首先,在客户端数据库tmpCart
中创建一个名为shopcart
的表,如下所示:
datab.transaction(function(transaction) {
transaction.executeSql(
'CREATE TABLE IF NOT EXISTS shopcart (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' +
'cart_sess varchar(50), cart_isbn varchar(30), cart_item_name varchar(100), cart_qty integer, cart_price float);'
);
});
JavaScript数据库API支持SQL事务,所有数据库查询必须在事务的上下文中执行。要执行标准SQL查询,需要调用事务对象的executeSql
方法。为此,调用datab
对象的transaction
方法,并传递给它一个匿名函数。然后将事务传递给匿名函数,以便可以调用事务对象的executeSql
方法。
executeSql
方法创建一个名为shopcart
的表(如果它不存在的话)。该表有六个字段:id、cart_sess、cart_isbn、cart_item_name、cart_qty和cart_price。id字段是主键。它的值不能为null,并且对于表的每一行都是唯一的。将此字段设置为AUTOINCREMENT,所以它的值将随着每行表的添加而增加1。
假设用户已经将一本书放入购物车,所以现在有一些购物车数据需要处理——会话id、ISBN、标题、数量和价格。这些数据分别存储在变量sid、isbn、title、qty和price中。将这些数据转移到客户端shopcart
表的一行中,如下所示:
datab.transaction(function(transaction) {
transaction.executeSql(
'INSERT INTO shopcart (cart_sess, cart_isbn, cart_item_name, cart_qty, cart_price) VALUES (?,?,?,?,?,?);',
[sid, isbn, title, qty, price],
function() {
// 成功执行SQL语句后的回调函数
},
displayerrormessage
);
});
注意:会话id用于会话管理——一种用于跟踪访问Web应用程序的用户的机制。服务器为当前会话生成一个唯一的id。
首先使用事务对象的executeSql
方法来执行SQL查询。需要将五个字段或列的数据传递给这个方法。VALUES括号中的五个问号(?)是占位符,它们将被数组[sid, ISBN, title, qty, price]中的值替换。第一个问号被sid变量的值替换,第二个问号被ISBN值替换,依此类推。
值数组后面是一个匿名函数,称为数据回调函数,其中可能包含在SQL语句成功执行后要执行的语句。例如,数据回调可能包含调用其他函数以显示确认消息或导航到另一个面板的调用。如果不希望在SQL语句成功执行后执行任何操作,可以像代码片段中实际所做的那样将这个函数留空。
片段的最后一部分,displayerrormessage,是对错误处理函数的调用,如果SQL语句失败,希望调用该函数。以下是displayerrormessage用法的示例:
function displayerrormessage(transaction, error) {
alert('Error: ' + error.message + ' has occurred with Code: ' + error.code);
return true;
}
displayerrormessage函数接收两个参数:事务对象和错误对象。错误对象显示错误消息和错误代码。将事务对象传递给displayerrormessage函数的原因是允许在函数内执行更多的SQL语句(如果需要的话)。displayerrormessage函数可以返回true以停止执行并回滚整个事务,或者返回false,在这种情况下,事务将继续。
表2包含了在执行客户端数据库表事务时生成的常见错误代码的快速查看。
错误代码 | 出现时 |
---|---|
0 | 事务因其他非数据库相关错误而失败。 |
1 | 事务因其他数据库相关错误而失败。 |
2 | 事务失败,因为数据库的版本与用户请求的版本不匹配。 |
3 | 事务失败,因为从数据库返回的数据太大。 |
4 | 事务失败,因为没有足够的存储空间,或者用户不希望数据库超过现有限制。 |
5 | 事务失败,因为事务包含了语法错误、参数数量不匹配、在只读事务中修改数据库的语句等。 |
6 | 事务失败,因为约束失败,例如,分配给两行的主字段具有相同的值。 |
如果不感兴趣捕获错误,可以省略数据回调和错误处理回调函数。如果这样做,代码片段将如下所示:
datab.transaction(function(transaction) {
transaction.executeSql(
'INSERT INTO shopcart (cart_sess, cart_isbn, cart_item_name, cart_qty, cart_price) VALUES (?,?,?,?,?,?);',
[sid, isbn, title, qty, price]
);
});