准备好的声明中的可选订单

时间:2012-12-05 19:55:20

标签: java mysql prepared-statement

我正在重构我的申请。我实际做的一件事是:

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];
    }
}

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

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

3 个答案:

答案 0 :(得分:1)

使用基本SQL库无法完成此操作。你被困住了,但你有几个选择。

  1. 使用String.format可能会更快。
  2. StringBuilder使用.append 绝对对您来说更快。
    • 不要对String使用+ =,除非它不经常使用(然后无关紧要)。 StringBuilder总是更快,特别是如果你可以很好地预测capacity。但是这里默认的16个字符可能就足够了(但是,如果不是,请使用更大的字符)。
  3. 可能最快的是开始使用Spring。即使用此sort课程。
  4. 以下是使用StringBuilder的代码版本,虽然Spring方式可能是最好的,但是您需要做更多的工作。 Check out Spring here.

    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();
    

答案 1 :(得分:0)

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

所以:你在java中有一个半数据库模型,如果你不打算使用更全面的模型,你可以用XML写出一堆SQL语句,比如{{ 3}}。收集SQL并按表对它们进行分组可能会有所帮助。

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

然而,遗留代码的重构应该在任何改进之前 使旧东西清洁和可维护。 拆分数据查询  从表示,删除丑陋的嵌套查询循环,在同一个表上收集查询。等等。

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

答案 2 :(得分:0)

  

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

“编译”是什么意思?如果您的意思是构建SQL字符串,那么与数据库通信的成本将始终主导字符串构建(我在不到3秒的时间内运行了原始代码一百万次)。担心让代码的这一部分可读。

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