我正在处理一个(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。答案 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对象,而不必操纵字符串,并担心你得到正确顺序的所有关键字和所有平衡。