简体   繁体   English

用Java处理丑陋的SQL

[英]Dealing with ugly SQL in Java

Here goes a SQL-Java coding style question... 这是一个SQL-Java编码风格的问题...

How do others here deal with creating complex custom queries in Java cleanly ? 这里的其他人如何处理干净地在Java中创建复杂的自定义查询?

I am speaking of the seemingly simple task of preparing a string which is the SQL statement to be executed. 我说的是准备一个似乎是要执行的SQL语句的字符串的看似简单的任务。

I am aware of HQL, and also of stored procedures, but honestly I don't really love these solutions. 我知道HQL以及存储过程,但是老实说我并不真正喜欢这些解决方案。 Perhaps I can be convinced differently. 也许可以说服我不同。 Stored procedures are annoying to deploy/maintain, and parsing performance is not such a huge issue in my case -- flexibility takes precedence. 存储过程部署/维护很烦人,而对我而言,解析性能并不是一个大问题-灵活性优先。 HQL seems like a big leap, and has some limitations for my complex queries. HQL似乎是一个巨大的飞跃,并且对我的复杂查询有一些限制。

TO be clear, I am talking of super-ugly looking code like this: 明确地说,我说的是看起来很丑陋的代码,如下所示:

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

Where the variables topTwenty are for example also subqueries created similarly. 例如,在变量topTwenty所在的地方,子查询也类似地创建。

I never thought I'd say this, but it was cleaner in PHP which had the multi-line string and $variable embedding in the strings. 我从没想过要这么说,但是在PHP中它比较干净,因为PHP中包含多行字符串和$ variable嵌入到字符串中。

Do people ever use a trivial templating library? 人们是否曾经使用过简单的模板库? How do you neatly keep the strings in the program? 您如何整齐地将字符串保留在程序中? Or do you put them in a separate file (also seems annoying to me somehow). 还是将它们放在单独的文件中(对我来说似乎也很烦)。

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

You probably want to look at parameterizing your queries which you can do with JDBC PreparedStatement s. 您可能想看看参数化查询,您可以使用JDBC PreparedStatement查询。 If you're coming from the PHP world, it's analogous to PDO. 如果您来自PHP世界,则类似于PDO。 Basically. 基本上。 all your dynamic $variable s from the PHP string you alluded to above, would be ? 您上面提到的PHP字符串中所有的动态$variable都将是? s in a parameterized query. 参数化查询中的。 The ? ? s get substituted in a safe (read proper escaping ) way by methods of the PreparedStatement implementation. 使用PreparedStatement实现的方法以安全的方式(以正确的转义方式)进行替换。

See Sun's PreparedStatement tutorial for examples and further explanation. 有关示例和更多说明,请参见Sun的PreparedStatement教程

Java has PrintFormat class which does very similar thing as sprintf in C, you might want to leverage it to format your query. Java具有PrintFormat类,该类与C中的sprintf十分相似,您可能想利用它来格式化查询。

Following code snippet is taken from http://java.sun.com/developer/technicalArticles/Programming/sprintf/ 以下代码段摘自http://java.sun.com/developer/technicalArticles/Programming/sprintf/

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

SQL构造集 ,这是我的项目。

What I do is to use String.format for table names and things that can't be parametrized, and this class (NamedPreparedStament), which allows to use good names for bind variables instead of question marks. 我要做的是将String.format用于表名和无法参数化的东西,以及此类 (NamedPreparedStament), 该类允许对绑定变量而不是问号使用好的名称。

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

You could try using StringBuilder.append() if you think that will make your code look cleaner: 如果您认为这会使代码看起来更简洁,则可以尝试使用StringBuilder.append():

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM