0

我正在重构我的应用程序。我实际上正在做的一件事是:

String sql = "select column1 from table2";
boolean isOrderbyAdded = false;
for(int i=1; i<N; i++) { // N is a known integer (e.g. 5)
    if(column[i]!=null) {
        if(!isOrderbyAdded) {
            sql += " order by "
            isOrderbyAdded = true;
        } else {
            sql += ", "
        }
        sql += column[i];
    }
}

我想将其更改为准备好的声明。有没有办法编写一个语句来检查是否在最终对结果进行排序之前指定了每个列名?

我的查询每天执行数百万次。我认为准备好的语句可以为我节省一些编译时间。

4

3 回答 3

1

这不能使用基本的 SQL 库来完成。你被卡住了,但你有几个选择。

  1. 使用String.format可能对您来说更快。
  2. 使用StringBuilderwith肯定.append会更快。
    • 永远不要将 += 用于Strings,除非它不经常使用(那么没关系)。StringBuilder总是更快,尤其是如果您可以预测capacity井。但是这里默认的多 16 个字符可能就足够了(不过,如果不是,请使用更大的字符)。
  3. 最快的可能是开始使用 Spring。即使用这个排序类。

这是您使用的代码版本StringBuilder,尽管 Spring 方式可能是最好的,但您需要做更多的工作。在这里查看春天。

StringBuilder sqlsb = new StringBuilder("select column1 from table2");
boolean isOrderbyAdded = false;
for(int i=1; i<N; i++) { // N is a known integer (e.g. 5)
  if(column[i]!=null) {
    if(!isOrderbyAdded) {
      sqlsb.append(" order by ");
          isOrderbyAdded = true;
    } else {
      sqlsb.append(", ");
    }
    sqlsb.append(column[i]);
  }
}
String sql = sqlsb.toString();
于 2012-12-05T20:10:32.003 回答
0

在您的代码中,SELECT 列是 ORDER BY 列的候选者。

所以:你在 java 中有一个半 DB 模型,如果你不想要一个更完整的模型,你可以有一个用 XML 写出的 SQL 语句池,就像在mybatis中一样。收集 SQL,并按表对它们进行分组可能会有所帮助。

寻找一个完整的模型:在 JPA 中(例如使用 eclipseLink),你有一个标准 api 用于类型安全的查询构建。

然而,遗留代码的重构应该在任何改进之前使旧的东西变得干净和可维护。从表示中拆分数据查询,删除丑陋的嵌套查询循环,在同一张表上收集查询。诸如此类。

是的,如果仅用于 SQL 注入和引号转义,使用准备好的语句会更好。

于 2012-12-05T20:31:38.560 回答
0

我的查询每天执行数百万次。我认为准备好的语句可以为我节省一些编译时间。

“编译”是什么意思?如果您的意思是构建 SQL 字符串,那么与数据库对话的成本将始终支配字符串构建(我在不到三秒的时间内运行了您的原始代码一百万次)。担心使那部分代码变得可读。

一个更重要的问题是查询计划是否会被正确缓存——它可能是,尽管对于排序顺序的每个组合都有一个单独的缓存条目。这并不奇怪,因为排序顺序很可能会改变执行计划。

于 2012-12-05T21:18:19.583 回答