这是一个非常开放的问题,但我认为它对SQL可读性非常有益。
所以你有一个Java程序,并且你试图从它调用一个怪物SQL语句,有许多子查询和连接。我的问题的起点是这样的字符串常量:
static string MONSTER_STATEMENT =
"SELECT " +
" fields" +
"WHERE "+
" fieldA = (SELECT a FROM TableC) " +
"AND fieldB IN (%s)" +
"AND fieldC = %d " +
"FROM "
" tableA INNER JOIN tableB ON ...";
稍后使用String.format填充并执行。
你有什么技巧让这种东西可读?你分开你的内部联接吗?你在字符串中缩进SQL本身吗?你把评论放在哪里?请分享你的武器库中的所有技巧。
答案 0 :(得分:1)
如果我使用像Management Studio这样的管理控制台直接查询数据库,我倾向于按照我的意愿格式化我的SQL语句。因此,当我构建一个SQL语句时,我会把时间放在空格和换行符中。消耗的额外空间与能够读取SQL的时间节省相比是无关紧要的,我应该将其打印出来或使用SQL Profiler捕获它。所以,我倾向于使用StringBuilder
来组合我的SQL:
StringBuilder sql = new StringBuilder();
sql.append("Select ....");
sql.append("\t\n, AdditionalCol, ...");
sql.append("\nFrom ...");
sql.append("\n Inner Join ...");
sql.append("\n On ColA = ...");
sql.append("\nWhere Col1 = (");
sql.append("\n Select a");
sql.append("\n From TableC");
sql.append("\n ");
sql.append("\n And ColB In(%s)");
sql.append("\n And ColC = %d");
答案 1 :(得分:1)
围绕构建过程的帮助程序类可能对您有所帮助。那可能是一个:http://openhms.sourceforge.net/sqlbuilder/
无论如何,总是要准备好陈述。
答案 2 :(得分:0)
这样复杂的SQL应该在一个准备好的语句中,而不是由String.format
组合在一起以避免SQL注入问题。
我执行以下两项操作之一:将其包装在可调用语句中或将其放在配置/ xml文件中。 Java源文件是复杂SQL的坏地方。
话虽如此,IDEA还有一种语言格式化功能,可以将Java中的字符串格式化为不同的语言(基于传递给它们的方法或基于注释),这样可以提供帮助。
编辑:鉴于您的情况,我同意可调用的语句可能不可行。准备好的语句仍然值得,即使对于内部开发,只是因为带有撇号的参数可以将所有内容都搞砸(即使没有攻击者),所以IMO还是值得做额外的工作来创建字符串代码中的动态(String.format或其他任何东西)仅用于不能作为参数传递的部分(如示例中的临时表名),然后将其用作准备语句,为其余部分传递适当的参数。
至于保持它不那么难看,它看起来像配置/ xml类型文件是我想要的。