跳至内容 Java Solaris 社区 Sun 商店 加入 SDN 我的个人档案 加入的益处
 
在 Sun Java Studio Creator 2 IDE 的 SQL 语句中使用参数
 
作者:Joel Brown,2006 年 1 月  
可以使用 Sun Java Studio Creator 2 IDE 及其查询编辑器来创建复杂的 SQL 查询。本技术文章介绍了在 SQL 语句中使用参数可以最大限度地提高查询的灵活性。本文还说明了如何以编程方式使用包含 WHERE 子句的 SELECT 语句,该子句用于处理每个请求中可能发生变化的条件(此处论述的大部分内容都是围绕着准备和执行 SQL 语句的基本 JDBC 代码展开的,不是专门说明 IDE 的)。

尽管本文没有论述 IDE 的查询编辑器,但可以使用查询编辑器来定义查询命令。但是,在查询中使用参数时,您需要编写一些代码,这些代码会设置参数的最低值。有关使用查询编辑器的详细信息,请参见功能简介文章 Java Studio Creator 2 查询编辑器。您还可以参阅最佳实例文章使用通用页面 Bean 设计元素,尤其是“使用参数化查询”部分。
 
目录
 
处理查询中发生变化的条件
问题
小结
 
处理查询中发生变化的条件

通常,可以使用两种方法来处理 SELECT 语句的 WHERE 子句中发生变化的条件:

  1. 对查询进行参数化处理
  2. 在运行时动态构造查询

我们将详细介绍这两种方法。

为了提高效率,应尽可能对查询进行参数化处理(即,在 SQL 语句中使用参数)。IDE 始终使用 java.sql.PreparedStatement 来执行查询,这意味着您只需编译一次参数化查询,在使用其他参数值时无需进行重新编译就可重用该查询了。这将提高应用程序的性能。

无论使用哪种方法,您都可以通过其行集来处理查询。通过将数据库表放在页面或组件上,将其添加到应用程序后,IDE 将自动创建一个行集(即对 javax.sql.RowSet 接口的实现)。SQL 查询是名为 command 的行集的字符串值属性。

对查询进行参数化处理

对查询进行参数化处理时,实际上是将包含参数的 WHERE 子句添加到 SELECT 语句中。WHERE 子句遵循了 JDBC 约定,即将问号 (?) 作为参数的占位符。例如,可以定义一个需要单个输入参数值的行集命令,如下所示:

SELECT personid, jobtitle FROM person WHERE name = ?

IDE 提供了两种方法将参数添加到查询中。您可以选择位于“概要”窗格的会话 Bean 中的行集对象,然后在“属性”窗格中直接更改 command 属性的文本值(请参见图 1)。

图 1:直接更改 command 属性
图 1:直接更改 command 属性

或者,可以在“概要”窗格的会话 Bean 中双击该行集以调用查询编辑器。在查询编辑器中,右键单击网格窗格中的某列,然后选择“添加查询条件”。在随后打开的对话框中,可以在查询中添加参数(请参见图 2)。

图 2:使用查询编辑器来添加选择条件
图 2:使用查询编辑器来添加选择条件

对命令或查询进行参数化处理后,在执行命令之前需要在运行时为每个输入参数设置一个值。您可以使用行集 setObject 方法来设置参数值。必须对设置的每个参数值进行编号,从 1 开始,后跟参数值,如下所示:

rowset.setObject(1, value ) ; // parameter numbers start at 1

在执行或重新执行查询之前,请确保调用 setObject。您可以在应用程序中选择的任何位置包含此调用。另外,为了安全起见,应确保参数值的对象类型与对应于 JDBC 数据库对象类型的 Java 对象类型相同(有关这些对应对象类型的列表,请参见“Java Studio Creator 2 页面 Bean 术语”中的“确定列数据类型”部分)。

在运行时动态构造查询

此方法需要在运行时为查询设置行集 command 属性值来生成 SQL 命令。您可以在生成的命令中使用任何有效的 SQL SELECT 语句。建议在设计时使用查询编辑器,以确保使用有效的列名并从查询中返回组件所绑定的任何列。

以下示例说明了如何在运行时生成用于接受用户输入值的行集命令。首先,设置基本的 SELECT 语句,并将其保存在 String 变量中:

String command = "SELECT personid, jobtitle FROM person";// save this
                                                         // constant value
                                                         // somewhere

然后,当应用程序捕获了用户输入的参数值时,使用行集 setCommand 方法来定义完整的 SQL 语句。请注意,您已将用户输入值转换为字符串,并将 WHERE 子句和输入值附加在存放 SELECT 语句的变量后面,如下所示:

rowset.setCommand (command + " WHERE name = " + value.toString() );
问题

您应该记住,在运行时生成包含输入参数的行集命令时可能存在一些缺陷。

  • 运行时查询性能可能会受到影响,因为数据库的查询优化器无法生成用于处理输入参数的最佳方案。使用 LIKE 运算符时这种情况尤为突出,特别是按如下方式使用该运算符:"name LIKE ?"。通常,最好按以下方式使用 LIKE 运算符:"name LIKE 'big%'"。

  • 使用 IN 运算符进行比较可能会出现问题。直到运行时,您可能都不知道包含了多少个参数值。即,您可能不知道是使用 "name IN (?,?)" 还是 "name IN (?,?,?)" 进行比较。

通常,如果要在运行时生成 SQL 语句,您希望在生成运行时部分之前 SQL 列表 (SELECT personid, jobtitle FROM person) 包含在行集 command 属性中。例如,您希望在查询编辑器中设置 SELECT 语句的基本部分,然后在运行时附加 WHERE 子句。

可以将行集 command 属性中的 SQL 与在运行时生成的语句进行共享。行集 command 属性最初是在会话 Bean 的 private _init 方法中设置的,可从会话 Bean 的 public init 方法中调用该方法(在 Java 源代码编辑器中打开 SessionBean1,然后在该 Bean 的 init 方法中打开称为“Creator 管理的组件初始化”的代码折叠部分以查看该调用)。您可以在 init 方法的结尾处添加您自己的代码,以将行集 command 的副本保存到所创建的属性中。

小结

本文说明了如何从 SQL 查询中获取最有用的内容。还介绍了如何使用 IDE 的查询编辑器来构造接受参数的查询。并详细地介绍了使用不同的行集命令来充分利用这些参数化查询,以及在运行时动态地构造这些查询。

相关信息
 
Joel Brown 专门研究数据库方面的内容,他负责了大部分的 Creator IDE 的数据库工作。他在使用数据库和编写业务应用程序方面已有 20 多年的经验。