Java 生成SQL查询变体的良好实践
我正在从事一个(Java)项目,该项目需要根据用户想要使用的过滤器对SQL查询进行不同的修改 我现在有4个以上的查询,它们都使用相同的表,需要相同的表联接,并且使用相同的“orderby”。目前我已经将这些查询硬编码到代码中,对此我不满意。我想动态地生成它们,但我很难找到解决方案,或者我是否应该费心生成它们 注意:我不能使用存储过程 例如:Java 生成SQL查询变体的良好实践,java,oracle,Java,Oracle,我正在从事一个(Java)项目,该项目需要根据用户想要使用的过滤器对SQL查询进行不同的修改 我现在有4个以上的查询,它们都使用相同的表,需要相同的表联接,并且使用相同的“orderby”。目前我已经将这些查询硬编码到代码中,对此我不满意。我想动态地生成它们,但我很难找到解决方案,或者我是否应该费心生成它们 注意:我不能使用存储过程 例如: SELECT t1.column1, t2.column2, t3.column3 FROM (SELECT column1, column2,
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。有不止一个很好的解决方案——有几种工具可以在Java中创建类型安全且易于操作的SQL字符串 但由于您使用的是Oracle,最好的方法可能是准备好语句 如果只有几个(比如说,少于十个)组合,您可以选择硬编码的SQL字符串。除此之外,您还希望以编程方式动态构建语句。仅使用JDBC并没有很好的方法,您可能需要花时间研究一些数据库访问库 为了避免在动态构建数据库查询时必须操作SQL字符串,请查看。或者,如果您想这样做,ORM(如JPA)也会有一个CriteriaBuilder
您仍然会有相同的条件语句和逻辑,但至少您可以处理Java对象,而不必操作字符串,担心所有关键字的顺序都正确,所有参数都平衡。我在项目中遇到过相同类型的问题。在某些情况下,我使用该模式创建了动态SQL语句。使用构建器的一个优点是,您可以针对所有条件组合对构建器进行单元测试。是的,您仍将有一些条件逻辑,但它们都将封装在SQL Builder中 这两个建议似乎不是唯一的。所有值得一试的数据访问库都会使用预先准备好的语句。是否有您推荐的或我应该创建自己的库?我使用了Hibernates Criteria API和JPA2 Criteria Builder API。IMHO说,这些API对于基本用途来说很好,但是随着您想要编写的查询变得更加复杂,这些API的实用性会急剧下降。使用这些API还假设您已经按照您想要查询数据的方式映射了实体关系。情况可能并非如此。因此,我总是使用自己的SQL生成器进行复杂的查询。正如@Thilo所提到的,如果您打算使用库,那么就有JOOQ和Querydsl。