Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.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—如何格式化SQL语句而不受Java字符串不变性的影响?_Java_Sql_Jdbc - Fatal编程技术网

Java—如何格式化SQL语句而不受Java字符串不变性的影响?

Java—如何格式化SQL语句而不受Java字符串不变性的影响?,java,sql,jdbc,Java,Sql,Jdbc,例如,我想创建以下SQL SELECT语句以提高JDBC的可读性: ResultSet result = statement.executeQuery( "SELECT " + "table1.*, " + "table2.someColumn " + "FROM " + "table1 " + "LEFT JOIN " + "table2 " +

例如,我想创建以下SQL SELECT语句以提高JDBC的可读性:

ResultSet result = statement.executeQuery(
        "SELECT " +
            "table1.*, " +
            "table2.someColumn " +
        "FROM " +
            "table1 " +
        "LEFT JOIN " +
            "table2 " +
        "ON " +
            "table1.column1 = table2.column2 " +
        "WHERE " +
            "date > today");
基本上,通过格式化SQL命令,尤其是较长的命令,它使编码时更易于阅读。缺点是每一行都是一个不可变字符串的实例,这会对性能和内存造成损失。是的,我可以使用StringBuffer,但这使得SQL代码再次无法读取,就像我有一条长长的SQL行一样

是的,在这种情况下,成本只有一次,但在某些情况下,我需要包括一些参数。添加?很好,并且再次最小化了字符串不可变的问题,但在某些情况下,SQL命令是动态生成的,这将导致在不可能使用参数的情况下,SQL命令略有不同

有没有一种方法可以在Java中编写此代码并保持代码的格式,而无需支付字符串不变性惩罚,也无需使用StringBuffer


注意:由于其他原因,我也无法将其写入文件,我将不在这里讨论。

使用stringbuffer/stringBuilder并使用逻辑保存格式化字符串,然后使用toString方法获取字符串。最后使用replaceAll获取不带行分隔符的字符串

StringBuffer strBuf=new StringBuffer("");
strBuf.append("SELECT );
strBuf.append("* );
..
要显示,请使用strBugf.toString

在查询中使用时

String Finalquery =strBuf.toString().replaceAll("\n","");;
或者,您也可以有一个字符串列表,但我更喜欢strinBuilder/Buffer而不是字符串列表


我真的不明白为什么您会对strigbuffer/stringBuilder的想法感到担忧,编译器应该注意这一点,但如果您愿意,可以将查询字符串设置为常量,并在编译时进行计算,几乎没有开销:

private static final String QUERY_STRING = "SELECT " +
            "table1.*, " +
            "table2.someColumn " +
        "FROM " +
            "table1 " +
        "LEFT JOIN " +
            "table2 " +
        "ON " +
            "table1.column1 = table2.column2 " +
        "WHERE " +
            "date > today";


我认为在幕后,不管怎样,当您使用+时,您都会得到一个StringBuilder/StringBuffer。根据官员的说法

字符串连接是通过StringBuilderor StringBuffer类及其append方法实现的


正如我在问题中所说,我试图避免使用StringBuffer,因为添加的文本使其更难阅读和扫描;引用这个问题,但在某些情况下,SQL命令是动态生成的,这将导致SQL命令略有不同,因此我不能将其设为常量。不幸的是,编译器不会像您建议的那样对字符串进行优化。如果您需要修改查询,如果您只需要查询参数或String.format,则只需使用准备好的语句,以防您需要异常的内容。在任何情况下,字符串模板都是常量。不幸的是,编译器不会像你建议的那样对字符串进行优化——它会的。Google字符串外部化我想我们都在把字符串连接作为一个性能问题来处理,这不是很严重。@StephaneGrenier在3.5 GHz左右的时候,我很乐意用代码的可读性来交换应用于字符串连接的一个无意义的性能指标。有没有想过你的SQL查询可能更像是一个瓶颈?为什么你会担心呢?以上都是文字数据。编译器将生成单个文本字符串。如果您担心串连字符串的性能影响,则尝试重新设计轮子。在Java中,这始终被视为编译时常量。不要只相信我,那么相信乔恩·斯基特:不,不要相信斯基特自己。但一定要相信他引用的JLS摘录。在你尝试优化之前,先看看这里是否有问题?这似乎更像是试图通过擦轮胎上的泥来让你的车跑得更快。这是真的。但是,如果你通过一个循环连接,在这个循环中字符串被赋值,然后再次被转换为附加在一起,那么你会发现+是一个StringBuffer吗?我在Javadocs中没有看到任何东西。如果在循环中进行测试,肯定会受到惩罚。我需要性能代码,因为我所做的工作规模很大。在Java 1.5和更高版本中,编译器优化使用了StringBuilder。在此之前,它使用StringBuilder。它在编译时总是一个字符串文本。OP没有要求更多“有趣”的解决方案,但如果他有,我会加入Antlr的stringtemplate库。我已经用它解决了类似的问题,取得了巨大的成功,但我不能说它的性能会比直接字符串连接更好。它肯定比StringBuffer.append更具可读性。
ResultSet result = statement.executeQuery(QUERY_STRING);