生成SQL查询变体的良好实践

时间:2014-11-19 23:39:09

标签: java oracle

我正在处理一个(Java)项目,该项目需要不同的SQL查询变体,具体取决于用户想要使用的过滤器。

我现在有4个以上的查询,它们都使用相同的表,需要相同的表连接,并使用相同的"顺序#34;。目前,我已将这些查询硬编码到代码中,我对此并不满意。我想动态生成它们,但我无法找出解决方案,或者我是否应该费心去生成它们。

注意:我无法使用存储过程。

实施例

SELECT t1.column1, t2.column2, t3.column3 FROM
     (SELECT column1, column2, sum(column3) FROM t1
          WHERE X = Y
          GROUP BY column1, column2
          ORDER BY column1)
LEFT JOIN t2 on t1.column1 = t2.column1
LEFT JOIN t3 on t1.column2 = t3.column2
WHERE Y = Z AND A = B
ORDER BY t1.column1

不同之处在于WHERE,SELECT和GROUP BY语句。我可以在动态部分之间放置嵌套的if语句,但这看起来太乱了。

if ()
    "SELECT A"
else
    "SELECT B"
+ "FROM T1"

if ()
    "WHERE x = y

"LEFT JOIN ..."
etc.

做这样的事情感觉不对。我应该坚持硬编码还是有更好的解决方案?

编辑:我把它包含在标签中,但我想在这里注意到我使用的是Oracle。

3 个答案:

答案 0 :(得分:1)

我在已完成的项目中遇到了同样类型的问题。在某些情况下,我使用Builder模式来创建动态SQL语句。使用Builder的一个优点是,您可以针对条件的所有组合对Builder进行单元测试。是的,您仍然会有一些条件逻辑,但它将全部封装在您的SQL Builder中。

答案 1 :(得分:0)

有很多好的解决方案 - 有几种工具可以用Java创建类型安全且易于操作的SQL字符串。

但是既然你使用的是Oracle,那么最好的方法就是准备好的语句。

http://en.wikipedia.org/wiki/Prepared_statement

https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

答案 2 :(得分:0)

如果只有少数(少于,比如说十个)组合,您可以选择硬编码的SQL字符串。不仅如此,您还希望以编程方式动态构建语句。使用JDBC没有好办法做到这一点,您可能需要花时间查看一些数据库访问库。

为避免在动态构建数据库查询时必须操纵SQL字符串,请查看jOOQ。或者,如果你想这样,ORM(如JPA)也会有CriteriaBuilder。

你仍然会有相同的条件语句和逻辑,但至少你可以使用Java对象,而不必操纵字符串,并担心你得到正确顺序的所有关键字和所有平衡。