Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 预处理语句中的可选order by_Java_Mysql_Prepared Statement - Fatal编程技术网

Java 预处理语句中的可选order by

Java 预处理语句中的可选order by,java,mysql,prepared-statement,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 "

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

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];
    }
}
String sql=“从表2中选择列1”;
布尔值isOrderbyAdded=false;

对于(inti=1;i来说,这不能用基本的SQL库来完成。你被卡住了,但是你有一些选择

  • 使用
    String.format
    可能会更快
  • StringBuilder
    .append
    一起使用肯定会更快。
    • 永远不要使用+=表示
      String
      s,除非不是经常使用(
      StringBuilder
      ),它总是更快,特别是如果你能预测油井的话。但是默认的16个字符在这里可能就足够了(如果不是,则使用更大的字符)
  • 最快的可能是开始使用Spring,即使用这个类
  • 下面是使用
    StringBuilder
    的代码版本,虽然Spring方式可能是最好的,但需要您做更多的工作

    StringBuilder sqlsb=新建StringBuilder(“从表2中选择列1”);
    布尔值isOrderbyAdded=false;
    
    对于代码中的(int i=1;i,SELECT列是ORDER BY列的候选列

    因此:您在java中有一个半DB模型,如果您不打算使用更完整的模型,您可以有一个以XML编写的SQL语句池,如中所示。收集SQL并按表对它们进行分组可能会有所帮助

    使用完整模型:在JPA中(例如使用eclipseLink),您有一个用于类型安全的查询构建的CriteriaAPI

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

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

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

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


    一个更重要的关注点是查询计划是否会被正确缓存——很可能是这样,尽管每个排序顺序组合都有一个单独的缓存项。这并不奇怪,因为排序顺序很可能会改变执行计划。

    因为您正在重构,所以将
    orderby添加到
    isOrderbyAdded
    :)在一条准备好的语句中,查询的位置将发生变化。顺序仍将以相同的方式改变。@SérgioMichels,因此没有办法避免每次重新编译此语句?与与与数据库通信的成本相比,构建SQL字符串的成本甚至微不足道。而您的代码肯定是斯特,原始代码在我的老式笔记本电脑上不到三秒就运行了一百万次。@gustafc:我想他的实际查询在现实世界中要比26个字符长得多。每次你在一台(不可变的)计算机上执行
    +=
    String
    ,它必须复制整个字符串。正确且无关紧要。你不会注意到这一点,因为大部分时间都花在与数据库服务器讨论TCP协议上。好吧,没错,但像LRC缓存和优化查询本身之类的事情超出了他的问题范围。我关心的不是字符串操作的开销。它而是关于准备好的语句的可重用性。我接受“不可能”作为答案。
    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();