使用 SQL 数据库的策略

Adobe AIR 1.0 和更高版本

应用程序可以通过各种方式来访问和使用本地 SQL 数据库。应用程序设计可能随应用程序代码的组织方式、操作执行方式的序列和计时等的不同而不同。所选技术可能影响开发应用程序的难易程度。它们可能影响在将来的更新中修改应用程序的难易程度。它们还可能影响从用户的角度看应用程序性能的高低。

分发预填充的数据库

在应用程序中使用 AIR 本地 SQL 数据库时,应用程序期望一个特定结构的表、列等的数据库。某些应用程序还期望在数据库文件中预填充特定数据。确保数据库具有正确结构的一种方法是,在应用程序代码中创建数据库。应用程序在加载时将检查在特定位置中是否存在其数据库文件。如果该文件不存在,则应用程序将执行一组命令来创建数据库文件,创建数据库结构并用初始数据填充表。

创建数据库及其表的代码常常很复杂。在应用程序的安装生存期内,它通常仅使用一次,但是仍增加了应用程序的大小和复杂性。作为以编程方式创建数据库、结构和数据的一种替代方法,可以随应用程序分发预填充的数据库。要分发预定义的数据库,请将数据库文件包括在应用程序的 AIR 包中。

与 AIR 包中包括的所有文件一样,捆绑的数据库文件安装在应用程序目录(由 File.applicationDirectory 属性表示的目录)中。但是,该目录中的文件是只读的。将 AIR 包中的文件用作“模板”数据库。用户第一次运行该应用程序时,会将原始数据库文件复制到用户的 指向应用程序存储目录 (或其他位置),并在应用程序中使用该数据库。

使用本地 SQL 数据库的最佳做法

下面列出了一组建议的方法,在使用本地 SQL 数据库时,可以通过这些方法提高应用程序的性能、安全性和易维护性。

预创建数据库连接

尽管应用程序在首次加载时不执行任何语句,但是在运行语句时,提前(如在应用程序初始启动之后)实例化 SQLConnection 对象并调用其 open() openAsync() 方法可以避免延迟。请参阅 连接到数据库

重用数据库连接

如果在应用程序的整个执行时间内访问某个数据库,请保存对 SQLConnection 实例的引用,并在整个应用程序中重用它,而不是先关闭再重新打开连接。请参阅 连接到数据库

推荐使用异步执行模式

编写数据访问代码时,可能很想同步执行操作而不是异步执行,因为使用同步操作通常需要更短的代码,并且代码的复杂性更低。但是,如 使用同步和异步数据库操作 中所述,同步操作可产生对用户而言很明显的性能影响,并损害用户对应用程序的体验。单个操作所用的时间随操作、尤其是它所涉及的数据量的不同而不同。例如,仅向数据库中添加一行的 SQL INSERT 语句所用的时间要比检索成千上万行数据的 SELECT 语句所用的时间少。但是,使用同步执行来执行多个操作时,这些操作通常串在一起。即使每个操作所用的时间非常短,但是在所有同步操作完成之前会冻结应用程序。因此,串在一起的多个操作的累积时间可能足以停止应用程序。

将异步操作用作一种标准方法,尤其是对于涉及大量行的操作。有一种技术可拆分大型 SELECT 语句结果集的处理,如 检索部分 SELECT 结果 所述。但是,此技术只能在异步执行模式下使用。只有在使用异步编程无法实现某些功能时,已考虑到应用程序的用户所要面临的性能折衷时,以及已测试应用程序以便了解对应用程序性能的影响程度时,才应使用同步操作。 使用异步执行可能涉及更复杂的编码。但是,请记住只需编写一次代码,但是应用程序用户必须重复使用它(或快或慢)。

在许多情况下,通过对要执行的每个 SQL 语句使用单独的 SQLStatement 实例,可以同时将多个 SQL 操作排队,这将使异步代码在代码编写方式上与同步代码类似。有关详细信息,请参阅 了解异步执行模式

使用单独的 SQL 语句,且不更改 SQLStatement 的 text 属性

对于在应用程序中多次执行的任何 SQL 语句,为每个 SQL 语句创建单独的 SQLStatement 实例。SQL 命令在每次执行时都使用该 SQLStatement 实例。例如,假定您要生成一个应用程序,它包括四个多次执行的不同 SQL 操作。在此情况下,创建四个单独的 SQLStatement 实例,并调用每个语句的 execute() 方法来运行它。避免对所有 SQL 语句使用单个 SQLStatement 实例,每次执行语句之前都重新定义其 text 属性。

使用语句参数

使用 SQLStatement 参数 — 从不将用户输入连接到语句文本中。使用参数会使应用程序更安全,因为这样可消除 SQL 注入攻击的可能性。这样就有可能在查询中使用对象(而不是仅使用 SQL 字面值)。这样还会提高语句的运行效率,因为可以重用语句,每次执行它们时无需将其重新编译。有关详细信息,请参阅 在语句中使用参数