Java 动态生成 SQL 查询 - ATHENA



我正在尝试根据用户输入生成sql查询。UI 上有 4 个搜索字段: FIRST_NAME, LAST_NAME, 主题, 标记

根据用户输入,我计划生成SQL查询。输入可以是任意组合。

例如:select * from TABLE where FIRST_NAME="some_value";

当给出FIRST_NAME并且其他字段为 null 时,需要生成此查询

select * from TABLE where FIRST_NAME="some_value" and LAST_NAME="some_value";

当给出FIRST_NAME和LAST_NAME并且其他字段为 null 时,需要生成此查询

由于有 4 个输入字段,因此可以生成的可能查询数为 24(阶乘为 4(。

一个想法是为所有 24 种情况编写 if 条件。

Java 伪代码:

String QUERY = "select * from TABLE where ";
if (FIRST_NAME!=null) {
QUERY = QUERY + "FIRST_NAME='use_input_value';"
}
if (LAST_NAME!=null) {
QUERY = QUERY + "LAST_NAME='use_input_value';"
}
if (SUBJECT!=null) {
QUERY = QUERY + "SUBJECT='use_input_value';"
}
if (MARKS!=null) {
QUERY = QUERY + "MARKS='use_input_value';"
}

我无法弄清楚如何使用 AND 编码为多个输入值生成 SQL 查询。 我已经了解了动态生成sql查询的概念,但无法进一步处理。

有人可以帮助我吗?

仅供参考:我已经完成了如何根据用户的选择动态生成SQL查询?,仍然无法根据用户输入生成查询字符串。

让我们考虑一下,如果您只是运行您编写的代码并且同时提供了FIRST_NAMELAST_NAME,会发生什么。你最终会得到这个:

select * from TABLE where FIRST_NAME='use_input_value';LAST_NAME='use_input_value';

这里有两个问题:

  1. 查询在语法上不正确。
  2. 它包含'use_input_value'的文本,而不是所需的值。

为了解决第一个问题,让我们首先在每个表达式的开头添加and,并删除分号,如下所示:

String QUERY = "select * from TABLE where";
if (FIRST_NAME!=null) {
QUERY = QUERY + " and FIRST_NAME='use_input_value'";
}

请注意and前面的空格。我们也可以在where之后删除空格。

现在,同时包含 FIRST_NAME 和 LAST_NAME 的查询将如下所示:

select * from TABLE where and FIRST_NAME='use_input_value' and LAST_NAME='use_input_value'

更好,但现在有一个额外的and.我们可以通过在查询开始时添加一个虚拟的始终为真的条件来解决这个问题:

String QUERY = "select * from TABLE where 1=1";

然后,在评估完所有条件后,我们附加一个分号,我们有一个有效的查询:

select * from TABLE where 1=1 and FIRST_NAME='use_input_value' and LAST_NAME='use_input_value';

(可能没有必要附加分号。大多数数据库不需要在像这样的单个查询末尾使用分号。

转到字符串文本。您应该改为添加一个占位符,同时将要使用的值添加到List中。

String QUERY = "select * from TABLE where";
List<String> args = new ArrayList<>();
if (FIRST_NAME!=null) {
QUERY = QUERY + " and FIRST_NAME=?";
args.add(FIRST_NAME);
}

处理完所有条件后,您将拥有一个带有 N'?' 占位符的字符串和一个带有 N 个值的List。此时,只需从 SQL 字符串准备一个查询并添加占位符。

PreparedStatement statement = conn.prepareStatement(QUERY);
for (int i = 0; i < args.size(); i++) {
statement.setString(i + 1, args[i]);
}

出于某种原因,在 JDBC API 中,列和参数从 1 开始索引,因此我们必须将 1 添加到i中才能生成参数索引。

然后执行PreparedStatement

最新更新