辅助功能*

H. Paul Robertson

H. Paul Robertson

Adobe
博客*

出版日期:
2008 年 2 月 28 日
用户级别:
中/高级
产品:
Adobe AIR

同步处理本地 SQL 数据库

我们特意将本应用程序设计得很简单。该应用程序在计算机的内存中创建一个数据库, 并在该数据库中创建一个表, 然后向数据库添加一些数据。单击 Load data (加载数据) 按钮, 然后检索数据, 并将其显示在屏幕上 (见图 1)。除了在单击按钮时加载数据以及在屏幕上显示这些数据之外, 不提供其它用户交互。特意这样做是为了使应用程序的重点完全放在数据库操作上。本范例应用程序演示 Adobe AIR 的以下功能:

  • 使用同步执行模式连接至本地 SQL 数据库
  • 同步创建和执行 SQL 语句:
    • 在数据库中创建表
    • 向数据库表中插入数据
    • 从数据库表中检索数据, 并在屏幕上显示这些数据

简单的本地数据库

图 1。通过本范例应用程序可以从数据库中加载数据。

注意: 本范例应用程序按原样提供, 用于教学目的。

要求

若要充分利用本篇文章, 您需要以下软件和文件:

Adobe AIR

Adobe AIR SDK

范例文件:

本范例应用程序包括以下文件:

  • SimpleSyncDBExampleHTML.html: 应用程序主要源代码
  • AIRAliases.js: AIR JavaScript 别名文件
  • application.xml: AIR 应用程序描述符文件
  • AIR 图标文件范例

必备知识

应具备构建 HTML 应用程序的一般经验。有关使用此快速入门指南的详细信息, 请参阅用 HTML 构建快速入门范例应用程序

了解代码

本部分将不一一介绍文件中的全部 HTML 标记, 而仅介绍专门针对 AIR 的 JavaScript 代码。

连接至本地 SQL 数据库

应用程序加载完毕时调用 init() 方法, 正如 body 标签的 onload 事件处理函数中所定义。在此方法中创建 SQLConnection 实例名 conn。 (在方法外声明变量 conn, 以使该变量对应用程序中的所有代码都可用。) 此 SQLConnection 对象建立到数据库的连接, 并由其它对象用于对该特定数据库执行操作。创建 SQLConnection 实例后, 即调用 open() 方法, 以同步执行模式打开到数据库的连接。

try
{
    conn.open(null);
}
catch (error)
{
    statustext.innerText = "Error opening database";
    air.trace("error.message:", error.message);
    air.trace("error.details:", error.details);

    return;
}
createTable();

在本例中, 将 null 作为参数传递至 open() 方法, 表示运行时将在计算机的内存中而非在磁盘位置中创建数据库。此外, 还可以 (使用 File 实例) 指定文件位置。然后, 运行时将打开该位置的数据库文件 (如果文件不存在, 则首先创建该文件)。执行该任务的代码如下所示:

var dbFile = air.File.applicationStorageDirectory.resolvePath("DBSample.db");
conn.open(dbFile);

air.File.applicationStorageDirectory 指向 AIR 应用程序的存储目录, 该目录的定义对于每个 AIR 应用程序都是独一无二的。

由于 open() 的调用被包围在 try..catch 块中, 因此如果调用失败, 则 init() 方法返回, 执行结束。假定 open() 操作成功并且打开了数据库连接, 则调用 createTable() 方法, 在数据库中创建表。

在数据库中创建表

createTable() 方法使用 SQLStatement 实例, 针对在 init() 方法中打开的数据库执行一条 SQL 命令。这条具体的 SQL 命令在数据库中创建一个名为“employees”的表, 其中包括四列。以下将代码分解, 分别介绍各段代码的作用:

  1. 创建名为 createStmt 的 SQLStatement 实例:

    createStmt = new air.SQLStatement();
  2. 指定对通过 SQLConnection 实例 conn 连接的数据库执行语句:

    createStmt.sqlConnection = conn;
  3. 定义用于创建数据库表的 SQL 语句文本。将表命名为“employees”。该表包含四列: “empId”、“firstName”、“lastName”和“salary”。

    var sql = "";
    sql += "CREATE TABLE IF NOT EXISTS employees ( ";
    sql += "empId INTEGER PRIMARY KEY AUTOINCREMENT, ";
    sql += "firstName TEXT, ";
    sql += "lastName TEXT, ";
    sql += "salary NUMERIC CHECK (salary >= 0) DEFAULT 0";
    sql += ")";
    createStmt.text = sql;
  4. 执行语句 (被包围在 try..catch 块中, 用于确定是否出错):

    createStmt.execute();

假定语句成功运行, 则创建“employees”表, 并调用 addData() 方法以执行过程中的下一步: 向新创建的表中添加数据。

向数据库表中插入数据

createTable() 方法一样, addData() 方法创建 SQLStatement, 在本例中是为了向数据库的“employees”表中插入一行数据。应用程序使用两个不同的 SQLStatement 实例 (insertStmtinsertStmt2) 插入两行数据:

statustext.innerText = "Adding data to table";
    
insertStmt = new air.SQLStatement();
insertStmt.sqlConnection = conn;
var sql = "";
sql += "INSERT INTO employees (firstName, lastName, salary) ";
sql += "VALUES ('Bob', 'Smith', 8000)";
insertStmt.text = sql;
    
insertStmt2 = new air.SQLStatement();
insertStmt2.sqlConnection = conn;
var sql2 = "";
sql2 += "INSERT INTO employees (firstName, lastName, salary) ";
sql2 += "VALUES ('John', 'Jones', 8200)";
insertStmt2.text = sql2;
    
try
{
    insertStmt.execute();
    insertStmt2.execute();
}
catch (error)
{
    statustext.innerText = "Error inserting data";

    air.trace("INSERT error:", error);
    air.trace("error.message:", error.message);
    air.trace("error.details:", error.details);
    
    return;
}
    
statustext.innerText = "Ready to load data";

如果两条语句都已执行完毕且未出错, 则将状态栏文本 (statustext.innerText) 更新为“Ready to load data” (准备加载数据), 此时应用程序已准备好从数据库中检索数据以及在屏幕上显示这些数据。

从数据库表中检索数据

就像创建表以及向表中插入数据一样, 从表中检索数据也是通过创建 SQLStatement 实例, 并将 SQL SELECT 语句作为 SQLStatement 实例的 text 属性。以下代码来自 getData() 方法, 这段代码创建并执行从“employees”表中检索所有行的 SELECT 语句:

selectStmt = new air.SQLStatement();
selectStmt.sqlConnection = conn;
var sql = "SELECT empId, firstName, lastName, salary FROM employees";
selectStmt.text = sql;
  
try
{
    selectStmt.execute();
}
catch (error)
{
    statustext.innerText = "Error loading data";
    air.trace("SELECT error:", error);
    air.trace("error.message:", error.message);
    air.trace("error.details:", error.details);
    
    return;
}
  
renderResult();

SELECT 语句执行完毕时, 将调用 renderResult() 方法。在 renderResult() 中, 通过调用 SQLStatement 实例的 getResult() 方法, 访问由 SELECT 语句检索的结果数据。调用 getResult() 将返回存储在变量 result 中的 SQLResult 实例;实际的各行结果包含在该变量的 data 属性的一个数组中。这些结果用于生成 HTML 表的各行, 具体方法是遍历 data 数组中的各行数据, 然后遍历每行中的各列, 为行和单元格生成 trtd 元素, 并将这些元素追加至一个名为 resultsGrid 的表 (已在 HTML 中定义):

function renderResult()
{
    statustext.innerText = "Data loaded";
    
    var result = selectStmt.getResult();
    
    var row;
    var cell;
    
    var tbl = document.getElementById("resultsGrid");
    tbl.innerHTML = "";
    
    var numRows = result.data.length;
    for (var i = 0; i < numRows; i++)
    {
    if (i == 0)
    {
        // 添加表格标题
        row = document.createElement("tr");
    
        for (col in result.data[i])
        {
            cell = document.createElement("th");
            cell.innerText = col;
            row.appendChild(cell);
        }
        
        tbl.appendChild(row);
    }
    
    // 遍历结果行对象中的各列
    row = document.createElement("tr");
    
    for (col in result.data[i])
    {
        cell = document.createElement("td");
        cell.innerText = result.data[i][col];
        row.appendChild(cell);
    }
    
    tbl.appendChild(row);
    }
}

关于作者

H. Paul Robertson 是 Adobe Systems 公司的平台开发人员文档团队的一名 ActionScript 开发人员/文档撰写人员。他曾作为一名 Web 应用程序开发人员与 Russell Chun 共同编写了《Macromedia Flash 8 Advanced: Visual QuickPro Guide》* (Peachpit 出版社, 2005 年)。Paul 是一名 Flash 认证开发人员, 拥有印地安那大学的教学系统技术专业硕士学位。在编写 Web 应用程序、撰写关于 Web 应用程序的稿件、讲授 Web 应用程序课程或更新博客*之余, Paul 喜欢收集各种厨房用具, 并乐于同他的三个孩子在乐高玩具、星球大战游戏等各种重大游艺项目上一争高下。