从数据库检索数据

Adobe AIR 1.0 和更高版本

从数据库检索数据分为以下两步。首先,执行 SQL SELECT 语句(描述要从数据库检索的一组数据)。然后,访问已检索的数据,并根据需要由应用程序显示或操作它。

执行 SELECT 语句

要从数据库检索现有数据,请使用 SQLStatement 实例。将相应的 SQL SELECT 语句分配给实例的 text 属性,然后调用其 execute() 方法。

有关 SELECT 语句的语法的详细信息,请参阅 本地数据库中的 SQL 支持

以下示例演示如何使用异步执行模式执行 SELECT 语句从名为“products”的表中检索数据:

// Include AIRAliases.js to use air.* shortcuts 
     
var selectStmt = new air.SQLStatement(); 
     
// A SQLConnection named "conn" has been created previously 
selectStmt.sqlConnection = conn; 
     
selectStmt.text = "SELECT itemId, itemName, price FROM products"; 
     
selectStmt.addEventListener(air.SQLEvent.RESULT, resultHandler); 
selectStmt.addEventListener(air.SQLErrorEvent.ERROR, errorHandler); 
     
selectStmt.execute(); 
     
function resultHandler(event) 
{ 
    var result = selectStmt.getResult(); 
     
    var numResults = result.data.length; 
    for (i = 0; i < numResults; i++) 
    { 
        var row = result.data[i]; 
        var output = "itemId: " + row.itemId; 
        output += "; itemName: " + row.itemName; 
        output += "; price: " + row.price; 
        air.trace(output); 
    } 
} 
     
function errorHandler(event) 
{ 
    // Information about the error is available in the 
    // event.error property, which is an instance of  
    // the SQLError class. 
}

以下示例演示如何使用同步执行模式执行 SELECT 语句从名为“产品”的表检索数据:

// Include AIRAliases.js to use air.* shortcuts 
     
var selectStmt = new air.SQLStatement(); 
     
// A SQLConnection named "conn" has been created previously 
selectStmt.sqlConnection = conn; 
     
selectStmt.text = "SELECT itemId, itemName, price FROM products"; 
     
try 
{ 
    selectStmt.execute(); 
     
    var result = selectStmt.getResult(); 
     
    var numResults = result.data.length; 
    for (i = 0; i < numResults; i++) 
    { 
        var row = result.data[i]; 
        var output = "itemId: " + row.itemId; 
        output += "; itemName: " + row.itemName; 
        output += "; price: " + row.price; 
        air.trace(output); 
    } 
} 
catch (error) 
{ 
    // Information about the error is available in the 
    // error variable, which is an instance of  
    // the SQLError class. 
}

在异步执行模式下,语句完成执行时,SQLStatement 实例调度 result 事件 ( SQLEvent.RESULT ),指示该语句已成功运行。或者,如果 Responder 对象作为参数传递给 execute() 方法,则调用 Responder 对象的结果处理函数。在同步执行模式下,执行暂停,直到 execute() 操作完成,然后继续执行下一行代码。

访问 SELECT 语句结果数据

SELECT 语句完成执行后,下一步是访问已检索的数据。通过调用 SQLStatement 对象的 getResult() 方法,从执行 SELECT 语句中检索结果数据:

var result = selectStatement.getResult();

getResult() 方法返回 SQLResult 对象。SQLResult 对象的 data 属性是一个包含 SELECT 语句的结果的数组:

var numResults = result.data.length; 
for (var i = 0; i < numResults; i++) 
{ 
    // row is an Object representing one row of result data 
    var row = result.data[i]; 
}

SELECT 结果集中的每行数据成为包含在 data 数组中的 Object 实例。该对象具有其名称与结果集的列名称匹配的属性。该属性包含结果集的列值。例如,假定 SELECT 语句指定一个结果集,该结果集具有名为“itemId”、“itemName”和“price”的三个列。对于结果集中的每一行,使用名为 itemId itemName price 的属性创建 Object 实例。这些属性包含来自其相应列的值。

以下代码清单定义其文本为 SELECT 语句的 SQLStatement 实例。该语句从名为 employees 的表的所有行中检索包含 firstName lastName 列值的行。此示例使用异步执行模式。执行完成时,调用 selectResult() 方法,使用 SQLStatement.getResult() 访问生成的数据行,使用 trace() 方法显示它们。请注意,此列表假定存在一个名为 conn 、已进行实例化并连接到数据库的 SQLConnection 实例。它还假定已创建“employees”表并为其填充了数据。

// Include AIRAliases.js to use air.* shortcuts 
     
// ... create and open the SQLConnection instance named conn ... 
     
// create the SQL statement 
var selectStmt = new air.SQLStatement(); 
selectStmt.sqlConnection = conn; 
     
// define the SQL text 
var sql =  
    "SELECT firstName, lastName " +  
    "FROM employees"; 
selectStmt.text = sql; 
     
// register listeners for the result and error events 
selectStmt.addEventListener(air.SQLEvent.RESULT, selectResult); 
selectStmt.addEventListener(air.SQLErrorEvent.ERROR, selectError); 
     
// execute the statement 
selectStmt.execute(); 
     
function selectResult(event) 
{ 
    // access the result data 
    var result = selectStmt.getResult(); 
     
    var numRows = result.data.length; 
    for (i = 0; i < numRows; i++) 
    { 
        var output = ""; 
        for (columnName in result.data[i]) 
        { 
            output += columnName + ": " + result.data[i][columnName] + "; "; 
        } 
        air.trace("row[" + i.toString() + "]\t", output); 
    } 
} 
     
function selectError(event) 
{ 
    air.trace("Error message:", event.error.message); 
    air.trace("Details:", event.error.details); 
}

以下代码清单演示与前面的代码清单相同的技术,但使用的是同步执行模式。该示例定义其文本为 SELECT 语句的 SQLStatement 实例。该语句从名为 employees 的表的所有行中检索包含 firstName lastName 列值的行。使用 SQLStatement.getResult() 访问生成的数据行,并使用 trace() 方法显示它们。请注意,此列表假定存在一个名为 conn 、已进行实例化并连接到数据库的 SQLConnection 实例。它还假定已创建“employees”表并为其填充了数据。

// Include AIRAliases.js to use air.* shortcuts 
     
// ... create and open the SQLConnection instance named conn ... 
     
// create the SQL statement 
var selectStmt = new air.SQLStatement(); 
selectStmt.sqlConnection = conn; 
     
// define the SQL text 
var sql =  
    "SELECT firstName, lastName " +  
    "FROM employees"; 
selectStmt.text = sql; 
     
try 
{ 
    // execute the statement 
    selectStmt.execute(); 
     
    // access the result data 
    var result = selectStmt.getResult(); 
     
    var numRows = result.data.length; 
    for (i = 0; i < numRows; i++) 
    { 
        var output = ""; 
        for (columnName in result.data[i]) 
        { 
            output += columnName + ": " + result.data[i][columnName] + "; "; 
        } 
        air.trace("row[" + i.toString() + "]\t", output); 
    } 
} 
catch (error) 
{ 
    air.trace("Error message:", error.message); 
    air.trace("Details:", error.details); 
}

定义 SELECT 结果数据的数据类型

默认情况下,由 SELECT 语句返回的每行都创建为 Object 实例,以结果集的列名作为属性名,每列的值作为其关联属性的值。但是,在执行 SQL SELECT 语句之前,可以将 SQLStatement 实例的 itemClass 属性设置为类。通过设置 itemClass 属性,由 SELECT 语句返回的每个行将创建为指定类的实例。通过将 SELECT 结果集中的列名与 itemClass 类中的属性名相匹配,运行时将结果列值分配给属性值。

作为 itemClass 属性值分配的任何类都必须具有不需要任何参数的构造函数。另外,对于由 SELECT 语句返回的每个列,该类必须具有一个单一的属性。如果 SELECT 列表中的列在 itemClass 类中没有相匹配的属性名称,系统会将其视为错误。

检索部分 SELECT 结果

默认情况下,执行 SELECT 语句会一次检索结果集的所有行。语句完成后,通常以某种方式处理检索的数据,如创建对象或在屏幕上显示数据。如果语句返回了大量的行,则同时处理所有数据可能对计算机要求过高,这又会导致用户界面无法自行重绘。

通过指示运行时一次返回特定数量的结果行,可以提高应用程序的感知性能。这样做会使初始结果数据更快地返回。它还允许您将结果行分到各组中,以便在处理每组行后更新用户界面。请注意,只有在异步执行模式下使用此技术才是可行的。

要检索部分 SELECT 结果,请为 SQLStatement.execute() 方法的第一个参数( prefetch 参数)指定一个值。 prefetch 参数指示首次执行语句时检索的行数。调用 SQLStatement 实例的 execute() 方法时,请指定 prefetch 参数值,并只检索由此值指定的行数:

// Include AIRAliases.js to use air.* shortcuts 
var stmt = new air.SQLStatement(); 
stmt.sqlConnection = conn; 
     
stmt.text = "SELECT ..."; 
     
stmt.addEventListener(air.SQLEvent.RESULT, selectResult); 
     
stmt.execute(20); // only the first 20 rows (or fewer) are returned

该语句调度 result 事件,指示第一组结果行是可用的。得到的 SQLResult 实例的 data 属性包含数据行,并且其 complete 属性指示是否存在要检索的其他结果行。要检索其他结果行,请调用 SQLStatement 实例的 next() 方法。与 execute() 方法一样,使用 next() 方法的第一个参数指示下次调度 result 事件时要检索的行数。

function selectResult(event) 
{ 
    var result = stmt.getResult(); 
    if (result.data != null) 
    { 
        // ... loop through the rows or perform other processing ... 
         
        if (!result.complete) 
        { 
            stmt.next(20); // retrieve the next 20 rows 
        } 
        else 
        { 
            stmt.removeEventListener(air.SQLEvent.RESULT, selectResult); 
        } 
    } 
}

每次 next() 方法返回后续的一组结果行时,SQLStatement 都会调度 result 事件。因此,可以使用同一侦听器函数继续处理结果(通过 next() 调用),直到检索了所有行。

有关详细信息,请参阅 SQLStatement.execute() 方法( prefetch 参数描述)和 SQLStatement.next() 方法的描述。