在Java中处理丑陋的SQL

时间:2009-12-17 03:21:58

标签: java sql mysql coding-style

这是一个SQL-Java编码风格问题......

其他人如何处理用Java 干净地创建复杂的自定义查询?

我说的是准备一个字符串这个看似简单的任务,这个字符串是要执行的SQL语句。

我知道HQL以及存储过程,但说实话,我并不喜欢这些解决方案。也许我可以用不同的方式说服。存储过程对于部署/维护很烦人,在我的情况下解析性能不是一个大问题 - 灵活性优先。 HQL似乎是一个很大的飞跃,并且对我的复杂查询有一些限制。

要明确的是,我说的是像这样超级难看的代码:

    return 
        "(" + topTwenty + ")" +
        "UNION " +
        "(" + twentyBeforeMe + ")" +
        "UNION " +
        "(" + meDummyQuery + ")" +
        "UNION " +
        "(" + twentyAfterMe + ")";

例如,topTwenty变量也是类似的子查询。

我从来没有想过我会说这个,但在PHP中它更清晰,它在字符串中嵌入了多行字符串和$ variable。

人们是否曾使用过琐碎的模板库?你如何整齐地保持程序中的字符串?或者你把它们放在一个单独的文件中(似乎也让我感到烦恼)。

6 个答案:

答案 0 :(得分:6)

如果不进入数据库抽象,您可以使用PreparedStatment使查询更具可读性 - 更不用说它有助于提高安全性。

答案 1 :(得分:3)

您可能希望查看参数化查询,您可以使用JDBC PreparedStatement进行查询。如果您来自PHP世界,那就类似于PDO。基本上。您在上面提到的PHP字符串中的所有动态$variable在参数化查询中都是??PreparedStatement实现的方式替换为安全(读取正确转义)方式。

有关示例和进一步说明,请参阅Sun's PreparedStatement tutorial

答案 2 :(得分:2)

Java的PrintFormat类与C中的sprintf非常相似,您可能希望利用它来格式化查询。

以下代码段取自http://java.sun.com/developer/technicalArticles/Programming/sprintf/

System.out.println(
new PrintfFormat("Pre %s Post%%").sprintf("target")
);  

答案 3 :(得分:1)

SQL Construction Set,顺便说一句,这是我的项目。

答案 4 :(得分:1)

我所做的是将String.format用于表名和无法参数化的东西,以及this class(NamedPreparedStament),它允许使用绑定变量的好名称而不是问号。

String sql = "SELECT id FROM %s WHERE id > :lastInsertedYesterday ";
NamedParameterStatement p = new NamedParameterStatement(con, 
                                    String.format(sql, "table1"));
p.setInt("lastInsertedYesterday", lastOne);

答案 5 :(得分:-1)

您可以尝试使用StringBuilder.append(),如果您认为这会使您的代码看起来更干净:

return new StringBuilder()
   .append("(").append(topTwenty).append(")")
   .toString();