Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 生成SQL查询变体的良好实践_Java_Oracle - Fatal编程技术网

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

Java 生成SQL查询变体的良好实践,java,oracle,Java,Oracle,我正在从事一个(Java)项目,该项目需要根据用户想要使用的过滤器对SQL查询进行不同的修改 我现在有4个以上的查询,它们都使用相同的表,需要相同的表联接,并且使用相同的“orderby”。目前我已经将这些查询硬编码到代码中,对此我不满意。我想动态地生成它们,但我很难找到解决方案,或者我是否应该费心生成它们 注意:我不能使用存储过程 例如: SELECT t1.column1, t2.column2, t3.column3 FROM (SELECT column1, column2,

我正在从事一个(Java)项目,该项目需要根据用户想要使用的过滤器对SQL查询进行不同的修改

我现在有4个以上的查询,它们都使用相同的表,需要相同的表联接,并且使用相同的“orderby”。目前我已经将这些查询硬编码到代码中,对此我不满意。我想动态地生成它们,但我很难找到解决方案,或者我是否应该费心生成它们

注意:我不能使用存储过程

例如:

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。